JPA and Hibernate - Criteria vs. JPQL or HQL
I mostly prefer Criteria Queries for dynamic queries. For example it is much easier to add some ordering dynamically or leave some parts (e.g. restrictions) out depending on some parameter.
On the other hand I'm using HQL for static and complex queries, because it's much easier to understand/read HQL. Also, HQL is a bit more powerful, I think, e.g. for different join types.
What to use: JPQL or Criteria API?
I'm pretty sure this has already been covered here on SO but I couldn't find the existing question. So, here is my point of view on the question:
- I find JPQL queries easier to write/read.
- I find the Criteria API nice for building dynamic queries.
Which is basically what you'll find in Hibernate: Criteria vs. HQL.
But there is one major difference between the JPA 2.0 Criteria API and the Hibernate's Criteria API that is worth mentioning: the JPA 2.0 Criteria API is a typesafe API and thus gives compile time checks, code completion, better refactoring support, etc.
However, I don't find that the benefits outweighs the ease of use of JPQL.
To sum up, I would favor JPQL, except for dynamic queries (e.g. for multi criteria search features).
Related questions
- Hibernate: Criteria vs. HQL
- What are some of the real world example where JPA2 Criteria API is more preferable?
More resources
- Hibernate Querying 102 : Criteria API
Hibernate criteria with a combination of AND/OR
You collect the criterions to a list and finally invoke criteria.add(Restrictions.or(list))
.
JPA Criteria API join query One To Many with condition
Assuming that your entities model is:
@Entity
class Enterprise {
...
@OneToMany
List<Product> products;
}
@Entity
class Product {
...
String status;
}
The following criteria should work:
CriteriaQuery<Enterprise> criteria = builder.createQuery(Enterprise.class);
Root<Author> root = criteria.from( Enterprise.class );
Join<Object, Object> productsJoin = root.join( "products" );
criteria.where( builder.equal( productsJoin.get("status"), "ACTIVE" ) );
List<Enterprise> result = session.createCriteria(criteria).getResultList();
It's the same as the HQL query:
from Enterprise e join e.products p
where p.status = 'ACTIVE'
If you want to load the association eagerly you can replace root.join
with root.fetch
:
CriteriaQuery<Enterprise> criteria = builder.createQuery(Enterprise.class);
Root<Author> root = criteria.from( Enterprise.class );
Join<Object, Object> productsJoin = (Join<Object, Object>)root.fetch( "products" );
criteria.where( builder.equal( productsJoin.get("status"), "ACTIVE" ) );
List<Enterprise> result = session.createCriteria(criteria).getResultList();
Here's the equivalent HQL query:
from Enterprise e join fetch e.products p
where p.status = 'ACTIVE'
You can find more examples in this article or in the Hibernate ORM documentation.
Are Restrictions and Projections deprecated from Hibernate 5.2 onwards?
Providing an answer for Hibernate 5.6.x:
Restrictions
is not marked deprecated. Check the corresponding JavaDoc.Projections
, likewise, is also not marked deprecated, see related JavaDoc.
As it stands now, both classes are not deprecated for version 5.6.x. Nevertheless, Hibernate’s Criteria API is deprecated as such, and ongoing development (version 6+) will focus on the JPA Criteria API.
However, it seems open for debate if the JPA community will move forward towards the vendor-agnostic CriteriaBuilder
.
Check the deprecation list of Hibernate‘s JavaDoc for an overview and further details.
Related Topics
Eclipse Windowbuilder, Overlapping JPAnels
The Simplest Way to Comma-Delimit a List
Spring Data JPA - "No Property Found for Type" Exception
Why Is an Instance Variable of the Superclass Not Overridden by a Subclass
How to Set Request Encoding in Tomcat
Why Converting from Float to Double Changes the Value
A Java API to Generate Java Source Files
JPA Hibernate One-To-One Relationship
Java; String Replace (Using Regular Expressions)
Why Does Int Num = Integer.Getinteger("123") Throw Nullpointerexception
Graphics Rendering in Title Bar
Generic Type Parameter Naming Convention for Java (With Multiple Chars)
Lambda Expression to Convert Array/List of String to Array/List of Integers
Execute .Jar File from a Java Program
Convert Each Animated Gif Frame to a Separate Bufferedimage
Instance Method Reference and Lambda Parameters