In the new Hibernate use of Criteria is Deprecated . How can I replace such code using org.hibernate.Criteria :

 Criteria criteria = session.createCriteria(Role.class); long id = ((Role) criteria.add(Restrictions.eq("name", name)).uniqueResult()).getId(); 

to its equivalent using javax.persistence.criteria.CriteriaBuilder from JPA ?

  • one
    All these criteria are so terrible to be typed in the answers. Check out whether this site en.wikibooks.org/wiki/Java_Persistence . There is a pdf for this site. This is called Java_Persistence.pdf. On the Internet you can buy or save books about jpa. Pro JPA 2 Mastering the Java Persistence API. - Sergey
  • I wanted to write a simple service to prepare for an interview with Java Junior. It is unlikely that I will ever get on it if I read a book on each technology. And this is after hours. :) But thanks for the link and the title of the book. Save yourself in the future. - faoxis

2 answers 2

em is an EntityManager instance.

 public Long query(String name) { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<Role> cq = cb.createQuery(Role.class); Root<Role> root = cq.from(Role.class); cq.where(cb.equal(root.get("name"), cb.parameter(String.class, "name"))); // cq.distinct(true); Query q = em.createQuery(cq); q.setParameter("name", name); List<Role> result = q.getResultList(); if (result.size() > 0) { return result.get(0).getId(); } return null; } 
  • Wow! In the new hibernate two lines turned into such a big method? - faoxis
  • This is a generic implementation that does not depend on Hibernate, but only uses JPA abstractions. Usually no one writes all these noodles for each request, but makes a wrapper and changes only cq.where . - Victor Khovanskiy
  • But why distinct? uniqueResult () matches getSingleResult (). try {return q.getSingleResult (). getId ()} catch (NoResultException) {return null; } - Sergey
  • Yes, I agree about unique, but catching Exception is still expensive. - Victor Khovanskiy

Well, when there is something to copy-paste (thanks, Victor)

 public Long query(String name) { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<Role> cq = cb.createQuery(Role.class); Root<Role> root = cq.from(Role.class); cq.where(cb.equal(root.get("name"), cb.parameter(String.class, "name"))); try { // Тут возможно надо делать приведение типов, // либо вызывать вариант метода, в котором указывается тип возвращаемого параметра // em.createQuery(cq, Role.class)... // либо и так сойдёт return em.createQuery(cq).setParameter("name", name).getSingleResult().getId(); } catch (NoResultException ex) { return null; } } 

or

 public Long query(String name) { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<Role> cq = cb.createQuery(Role.class); Root<Role> root = cq.from(Role.class); cq.where(cb.equal(root.get("name"), cb.parameter(String.class, "name"))); List<Role> roles = em.createQuery(cq).setParameter("name", name).getResultList(); return roles.isEmpty() ? null : roles.get(0).getId(); } 

Well, that is, a variant of Victor without extra distinct and in places assembled in one line at the expense of the fluent, which is widely used in JPA API.

If you are using static metamodel generation, then root.get ("name") is replaced by root.get (Role_.name). Type safe. Cho. Otherwise on the fig you generally criteria, when there is a text JPQL, and even better than SQL?

  • SQL is clearly not better if we want to abstract from the syntax of the database. For most applications, JPQL will suffice. - Victor Khovanskiy Nov.
  • Well, this is a joke. Although in every joke there is a grain of truth, and a large one. For example, I often use specific queries: full-text search, recursive cte, which JPA could hardly have planned and will ever be. Yes, even lousy left join is not done in JPA. As for the abstraction from the database ... But who really needs it. Right this base is changed every day. And the syntax in the part of the JPQL being covered is generally the same for everyone. - Sergey
  • Abstraction in the case when you need to maintain multiple databases (yes, it happens). - Victor Khovanskiy
  • It happens of course. I myself saw the Chinese product on Delphi, where there is no trace of abstraction (BDE does not count, for even the Chinese did not associate with it). But it worked the same. And supported all more or less well-known commercial bases. Well, of course the Chinese are easier. Their billion. One is querying for Oracle, the other is for DB2, etc. for MSSQL, for sybase. The rest of them perform. - Sergey