web-dev-qa-db-ja.com

Hibernate 5.2のSharedSessionContract.createCriteria(Class persistentClass)の正しい代替

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.htmlhttps://docs.jboss.org/hibernate/orm/5.2/ javadocs/org/hibernate/SharedSessionContract.html#createCriteria-Java.lang.Class-

ドキュメントでは、JPA基準を使用することを推奨しています。上記の背景に基づいたいくつかの質問を以下に示します。

  1. EntityManagerを使用しておらず、HibernateDAOSupportとHibernateTemplateに大きく依存しているため、sessionまたはsessionFactoryを使用してJAP基準を使用するにはどうすればよいですか?

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

これに対処するより良い方法がある場合は、HibernateDAOSupportとHibernateTemplateの使用を変更したくないので、提案してください。

23

以下で説明するように、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();
5
Akanksha

ドキュメントのリンクに続く状態は次のとおりです。

「非推奨と見なされるべきレガシーHibernate org.hibernate.Criteria API」

したがって、単にDetachedCriteriaに切り替えると、現在の減価償却はなくなりますが、JPA基準(org.hibernate.criterion.Restrictionsなどをサポートしない)を使用することが提案されます。それは不明確であり、ロードマップはあまり役に立ちません。

それは言及しています:

「最終的に、Hibernate固有の基準機能は、JPA javax.persistence.criteria.CriteriaQueryの拡張機能として移植されます。」

これでこれ以上得られましたか?

3
gregh

Hibernate 5.2では、_org.hibernate.Session_は_javax.persistence.EntityManager_を実装するため、Sessionを直接使用して条件クエリを作成できます。 JPA-Criteria API を参照してください。

ただし、hibernate 5.2.1.Finalにバグがある可能性があります。JPACriteria API _TypedQuery#getResultList_を呼び出し、代わりにQuery#list()を呼び出すと、setCacheableが機能しません。

_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