JPA and Hibernate - Criteria VS. Jpql or Hql

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



Leave a reply



Submit