在Hibernate 5.2中更正SharedSessionContract.createCriteria(Class persistentClass)的替代方法

时间:2016-06-16 11:11:18

标签: java spring hibernate hibernate-5.x

我正在从Hibernate 3.x升级到最新的Hibernate 5.2.0 FINAL。在我的旧代码中,我们使用标准查询,如下所示。

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 Criteria。以下是基于上述背景的几个问题。

  1. 由于我们没有使用EntityManager并且严重依赖于HibernateDAOSupport和HibernateTemplate,我如何使用session或sessionFactory来使用JAP Criteria?

  2. 如果我使用DetachedCriteria,如下面的代码片段,它将与之前的实现相同,或者下面的代码将为我们提供与会话无关的结果?

    DetachedCriteria criteria = DetachedCriteria.forClass(Employee.class);
    criteria.add(Restrictions.eq("Department", department));
    return (List<Employee>) getHibernateTemplate().findByCriteria(criteria);
    
  3. 另外,如果我以下面提到的方式使用DetachedCriteria,它将与我的旧代码具有相同的影响。

    Session session  =getHibernateTemplate().getSessionFactory().getCurrentSession();
    DetachedCriteria criteria = DetachedCriteria.forClass(Employee.class);
    criteria.add(Restrictions.eq("Department", department));
    return criteria .getExecutableCriteria(session).list();
    
  4. 如果有更好的方法可以解决这个问题,请建议我不要更改HibernateDAOSupport和HibernateTemplate的使用。

3 个答案:

答案 0 :(得分:5)

使用 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();

答案 1 :(得分:3)

以下文档链接为:

“遗留Hibernate org.hibernate.Criteria API,应该被视为已弃用”

因此,只需切换到DetachedCriteria即可摆脱当前的折旧,但建议使用JPA Criteria(不支持org.hibernate.criterion.Restrictions等)。目前还不清楚,路线图没有多大帮助。

确实提到:

“最终,特定于Hibernate的标准功能将被移植为JPA javax.persistence.criteria.CriteriaQuery的扩展”

你对此有何进一步了解?

答案 2 :(得分:3)

在hibernate 5.2中,org.hibernate.Session实现javax.persistence.EntityManager,因此您可以直接使用Session创建条件查询。见JPA - Criteria API

但是hibernate 5.2.1.Final中可能存在错误,如果调用JPA Criteria API setCacheable,则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
}