web-dev-qa-db-fra.com

Alternative correcte à SharedSessionContract.createCriteria (Class persistentClass) dans Hibernate 5.2

Je passe à la dernière version d'Hibernate 5.2.0 FINAL à partir d'Hibernate 3.x. Dans mon ancien code, nous utilisions des requêtes de critères comme ci-dessous.

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

Depuis Hibernate 5.2.0, la méthode createCriteria () est obsolète. Qui peut être trouvé dans la documentation suivante.

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 -

La documentation suggère d'utiliser les critères JPA. Voici les quelques questions que j'ai basées sur le contexte ci-dessus.

  1. Étant donné que nous n'utilisons pas EntityManager et que nous sommes fortement tributaires de HibernateDAOSupport et HibernateTemplate, comment puis-je utiliser les critères JAP à l'aide de la session ou sessionFactory?

  2. Si j'utilise DetachedCriteria comme dans l'extrait de code ci-dessous, est-ce que ce sera la même que la mise en œuvre précédente ou le code ci-dessous nous donnera des résultats indépendants de la session?

    DetachedCriteria criteria = DetachedCriteria.forClass(Employee.class);
    criteria.add(Restrictions.eq("Department", department));
    return (List<Employee>) getHibernateTemplate().findByCriteria(criteria);
    
  3. Également comme alternative, si j'utilise les DetachedCriteria de la manière mentionnée ci-dessous, cela aura-t-il le même impact que mon ancien code.

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

S'il y a une meilleure façon de gérer cela, veuillez suggérer car je ne veux pas changer l'utilisation de HibernateDAOSupport et HibernateTemplate.

23
Smruti R Tripathy

Utilisez CriteriaBuilder comme décrit ci-dessous:

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

Le lien suivant vers le document indique:

"API Hibernate org.hibernate.Criteria héritée, qui doit être considérée comme obsolète"

Donc, le simple passage à DetachedCriteria supprimera la dépréciation actuelle, mais cela suggérera d'utiliser les critères JPA (qui ne prennent pas en charge org.hibernate.criterion.Restrictions, etc.). Ce n'est pas clair et la feuille de route n'est pas d'une grande aide.

Il mentionne:

"Finalement, les fonctionnalités de critères spécifiques à Hibernate seront portées en tant qu'extensions de la JPA javax.persistence.criteria.CriteriaQuery"

Avez-vous approfondi cela?

3
gregh

Dans hibernate 5.2, org.hibernate.Session Implémente javax.persistence.EntityManager, Vous pouvez donc créer directement une requête de critères à l'aide de Session. Voir JPA - API de critères .

Mais il peut y avoir un bogue dans hibernate 5.2.1. Final, setCacheable ne fonctionne pas si appelez l'API JPA Criteria TypedQuery#getResultList, Appelez plutôt Query#list() à la place.

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
}
3
user2168746