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

15,339

Solution 1

Use CriteriaBuilder as described below:

//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();

Solution 2

Following the doc link is states:

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

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.

It does mention:

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

Did you get any further with this?

Solution 3

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

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

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
}
Share:
15,339
Smruti R Tripathy
Author by

Smruti R Tripathy

Passionate about large-scale software development, performance tuning etc :)

Updated on June 04, 2022

Comments

  • Smruti R Tripathy
    Smruti R Tripathy almost 2 years

    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.

    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.

    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.

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

    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.

    • russellhoff
      russellhoff almost 8 years
      I'm glad I'm not the unique in the world confused with this sudden change in Hibernate (considering I came from 5.1). I don't know whether to start thinking how to implement with criteria or going back to 5.1.