java Hibernate 5.2 中 SharedSessionContract.createCriteria(Class persistentClass) 的正确替代方案

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37857482/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 02:53:52  来源:igfitidea点击:

Correct alternative to SharedSessionContract.createCriteria(Class persistentClass) in Hibernate 5.2

javaspringhibernatehibernate-5.x

提问by Smruti R Tripathy

I am upgrading to latest Hibernate 5.2.0 FINAL from Hibernate 3.x. In my old code we were using criteria queries as below.

我正在从 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();

Now from Hibernate 5.2.0 the createCriteria() method has been deprecated. Which can be found from the following documentation.

现在从 Hibernate 5.2.0 开始, createCriteria() 方法已被弃用。可以从以下文档中找到。

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

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-

The documentation suggests to use JPA Criteria. Below are the few questions I have based on the above background.

该文档建议使用 JPA Criteria。以下是我根据上述背景提出的几个问题。

  1. Since we are not using the EntityManager and heavily dependent on the HibernateDAOSupport and HibernateTemplate , how I can use the JAP Criteria using the session or sessionFactory ?

  2. If I use DetachedCriteria as in the below code snippet is it going to be the same as previous implementation or the below code will give us session independent results ?

    DetachedCriteria criteria = DetachedCriteria.forClass(Employee.class);
    criteria.add(Restrictions.eq("Department", department));
    return (List<Employee>) getHibernateTemplate().findByCriteria(criteria);
    
  3. Also as an alternative , If I use the DetachedCriteria in below mentioned way is it going to have the same impact as of my old code.

    Session session  =getHibernateTemplate().getSessionFactory().getCurrentSession();
    DetachedCriteria criteria = DetachedCriteria.forClass(Employee.class);
    criteria.add(Restrictions.eq("Department", department));
    return criteria .getExecutableCriteria(session).list();
    
  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();
    

If there is a better way to deal with this please suggest as I don't want to change the use of HibernateDAOSupport and HibernateTemplate.

如果有更好的方法来解决这个问题,请提出建议,因为我不想改变 HibernateDAOSupport 和 HibernateTemplate 的使用。

回答by Akanksha

Use CriteriaBuilderas described below:

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

回答by gregh

Following the doc link is states:

在文档链接之后是状态:

"legacy Hibernate org.hibernate.Criteria API, which should be considered deprecated"

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

So just switching to DetachedCriteria will get rid of the current depreciation but its suggesting to use the JPA Criteria (which does not support org.hibernate.criterion.Restrictions etc). It is unclear and the roadmap is not much help.

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

It does mention:

它确实提到:

"Eventually, Hibernate-specific criteria features will be ported as extensions to the JPA javax.persistence.criteria.CriteriaQuery"

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

Did you get any further with this?

你对这个有进一步的了解吗?

回答by user2168746

In hibernate 5.2, org.hibernate.Sessionimplements javax.persistence.EntityManager, so you can create criteria query using Sessiondirectly. See JPA - Criteria API.

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

But there may be a bug in hibernate 5.2.1.Final, setCacheabledoes not work if call JPA Criteria API TypedQuery#getResultList, call Query#list()instead.

但是 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
}