Подтвердить что ты не робот

Правильная альтернатива SharedSessionContract.createCriteria(класс persistentClass) в Hibernate 5.2

Я обновляю до последнего Hibernate 5.2.0 FINAL из Hibernate 3.x. В моем старом коде мы использовали критерии запросов, как показано ниже.

Session session =getHibernateTemplate().getSessionFactory().getCurrentSession();
Criteria criteria = session.createCriteria(Employee.class);
criteria.add(Restrictions.eq("Department", department));
return criteria.list();

Теперь из Hibernate 5.2.0 метод createCriteria() устарел. Это можно найти в следующей документации.

https://docs.jboss.org/hibernate/orm/5.2/javadocs/deprecated-list.html https://docs.jboss.org/hibernate/orm/5.2/javadocs/org/hibernate/SharedSessionContract.html#createCriteria-java.lang.Class-

В документации предлагается использовать критерии JPA. Ниже приведены несколько вопросов, которые я основывал на приведенном выше фоне.

  • Поскольку мы не используем EntityManager и сильно зависим от HibernateDAOSupport и HibernateTemplate, как я могу использовать критерии JAP с помощью сеанса или sessionFactory?

  • Если я использую DetachedCriteria, как в приведенном ниже фрагменте кода, он будет таким же, как предыдущая реализация, или приведенный ниже код даст нам независимые от сеанса результаты?

    DetachedCriteria criteria = DetachedCriteria.forClass(Employee.class);
    criteria.add(Restrictions.eq("Department", department));
    return (List<Employee>) getHibernateTemplate().findByCriteria(criteria);
    
  • Также как альтернатива, если я использую DetachedCriteria ниже, это будет иметь то же влияние, что и на мой старый код.

    Session session  =getHibernateTemplate().getSessionFactory().getCurrentSession();
    DetachedCriteria criteria = DetachedCriteria.forClass(Employee.class);
    criteria.add(Restrictions.eq("Department", department));
    return criteria .getExecutableCriteria(session).list();
    

Если есть лучший способ справиться с этим, предложите, поскольку я не хочу менять использование HibernateDAOSupport и HibernateTemplate.

4b9b3361

Ответ 1

Используйте CriteriaBuilder, как описано ниже:

//Use below imports:
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;

//creating session. This you can create in your own way.
Configuration cfg = new Configuration();
cfg.configure("hibernate.cfg.xml");
cfg.addAnnotatedClass(Employee.class);

SessionFactory factory = cfg.buildSessionFactory();
Session session = factory.openSession();

//**creating CriteriaBuilder**
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Employee> criteria = builder.createQuery(Employee.class);
Root<Employee> employeeRoot=criteria.from(Employee.class);
criteria.select(employeeRoot);

//**Adding where clause**
criteria.where(builder.equal(employeeRoot.get("employeeId"), "E01"));
List<Employee> employeeList=session.createQuery(criteria).getResultList();

Ответ 2

После ссылки doc есть состояния:

"устаревший API-интерфейс Hibernate org.hibernate.Criteria, который следует считать устаревшим"

Таким образом, просто переключение на DetachedCriteria избавится от текущей амортизации, но предложит использовать критерии JPA (который не поддерживает org.hibernate.criterion.Restrictions и т.д.). Это неясно, и дорожная карта не очень помогает.

Он упоминает:

"В конце концов, характеристики критериев, зависящие от Hibernate, будут перенесены как расширения JPA javax.persistence.criteria.CriteriaQuery"

С этим вы получили больше?

Ответ 3

В hibernate 5.2, org.hibernate.Session реализует javax.persistence.EntityManager, поэтому вы можете напрямую создать запрос критериев, используя Session. См. JPA - API критериев.

Но может быть ошибка в hibernate 5.2.1. Final, setCacheable не работает, если вызывается JPA Criteria API TypedQuery#getResultList, вызовите Query#list().

public <T> T getAll(Class<T> clazz, boolean cache){
    CriteriaQuery<T> query = getCurrentSession().getCriteriaBuilder().createQuery(clazz);
    query.select(query.from(clazz));
    Query<T> q = getCurrentSession().createQuery(query);  // CriteriaQueryTypeQueryAdapter instance
    q.setCacheable(cache); // execute AbstractProducedQuery#setCacheable
//    return q.getResultList(); // CriteriaQueryTypeQueryAdapter#getResultList(), cache not works
    return q.list(); // AbstractProducedQuery#list() cache may be enabled
}