Hibernate.orgCommunity Documentation

Chapter 12. Criteria

Table of Contents

12.1. Typed criteria queries
12.1.1. Selecting an entity
12.1.2. Selecting an expression
12.1.3. Selecting multiple values
12.1.4. Selecting a wrapper
12.2. Tuple criteria queries
12.3. FROM clause
12.3.1. Roots
12.3.2. Joins
12.3.3. Fetches
12.4. Path expressions
12.5. Using parameters

Criteria queries offer a type-safe alternative to HQL, JPQL and native-sql queries.

Important

Hibernate offers an older, legacy org.hibernate.Criteria API which should be considered deprecated. No feature development will target those APIs. Eventually, Hibernate-specific criteria features will be ported as extensions to the JPA javax.persistence.criteria.CriteriaQuery. For details on the org.hibernate.Criteria API, see ???.

This chapter will focus on the JPA APIs for declaring type-safe criteria queries.

Criteria queries are a programmatic, type-safe way to express a query. They are type-safe in terms of using interfaces and classes to represent various structural parts of a query such as the query itself, or the select clause, or an order-by, etc. They can also be type-safe in terms of referencing attributes as we will see in a bit. Users of the older Hibernate org.hibernate.Criteria query API will recognize the general approach, though we believe the JPA API to be superior as it represents a clean look at the lessons learned from that API.

Criteria queries are essentially an object graph, where each part of the graph represents an increasing (as we navigate down this graph) more atomic part of query. The first step in performing a criteria query is building this graph. The javax.persistence.criteria.CriteriaBuilder interface is the first thing with which you need to become acquainted to begin using criteria queries. Its role is that of a factory for all the individual pieces of the criteria. You obtain a javax.persistence.criteria.CriteriaBuilder instance by calling the getCriteriaBuilder method of either javax.persistence.EntityManagerFactory or javax.persistence.EntityManager.

The next step is to obtain a javax.persistence.criteria.CriteriaQuery. This is accomplished using one of the 3 methods on javax.persistence.criteria.CriteriaBuilder for this purpose:

<T> CriteriaQuery<T> createQuery(Class<T> resultClass);
CriteriaQuery<Tuple> createTupleQuery();
CriteriaQuery<Object> createQuery();

Each serves a different purpose depending on the expected type of the query results.

Note

Chapter 6 Criteria API of the JPA Specification already contains a decent amount of reference material pertaining to the various parts of a criteria query. So rather than duplicate all that content here, lets instead look at some of the more widely anticipated usages of the API.

The type of the criteria query (aka the <T>) indicates the expected types in the query result. This might be an entity, an Integer, or any other object.

There are actually a few different ways to select multiple values using criteria queries. We will explore 2 options here, but an alternative recommended approach is to use tuples as described in Section 12.2, “Tuple criteria queries”. Or consider a wrapper query; see Section 12.1.4, “Selecting a wrapper” for details.


Technically this is classified as a typed query, but you can see from handling the results that this is sort of misleading. Anyway, the expected result type here is an array.

The example then uses the array method of javax.persistence.criteria.CriteriaBuilder which explicitly combines individual selections into a javax.persistence.criteria.CompoundSelection.


Just as we saw in Example 12.3, “Selecting an array” we have a typed criteria query returning an Object array. Both queries are functionally equivalent. This second example uses the multiselect method which behaves slightly differently based on the type given when the criteria query was first built, but in this case it says to select and return an Object[].

Another alternative to Section 12.1.3, “Selecting multiple values” is to instead select an object that will wrap the multiple values. Going back to the example query there, rather than returning an array of [Person#id, Person#age] instead declare a class that holds these values and instead return that.


First we see the simple definition of the wrapper object we will be using to wrap our result values. Specifically notice the constructor and its argument types. Since we will be returning PersonWrapper objects, we use PersonWrapper as the type of our criteria query.

This example illustrates the use of the javax.persistence.criteria.CriteriaBuilder method construct which is used to build a wrapper expression. For every row in the result we are saying we would like a PersonWrapper instantiated with the remaining arguments by the matching constructor. This wrapper expression is then passed as the select.

A better approach to Section 12.1.3, “Selecting multiple values” is to use either a wrapper (which we just saw in Section 12.1.4, “Selecting a wrapper”) or using the javax.persistence.Tuple contract.


This example illustrates accessing the query results through the javax.persistence.Tuple interface. The example uses the explicit createTupleQuery of javax.persistence.criteria.CriteriaBuilder. An alternate approach is to use createQuery passing Tuple.class.

Again we see the use of the multiselect method, just like in Example 12.4, “Selecting an array (2)”. The difference here is that the type of the javax.persistence.criteria.CriteriaQuery was defined as javax.persistence.Tuple so the compound selections in this case are interpreted to be the tuple elements.

The javax.persistence.Tuple contract provides 3 forms of access to the underlying elements:

typed

The Example 12.6, “Selecting a tuple” example illustrates this form of access in the tuple.get( idPath ) and tuple.get( agePath ) calls. This allows typed access to the underlying tuple values based on the javax.persistence.TupleElement expressions used to build the criteria.

positional

Allows access to the underlying tuple values based on the position. The simple Object get(int position) form is very similar to the access illustrated in Example 12.3, “Selecting an array” and Example 12.4, “Selecting an array (2)”. The <X> X get(int position, Class<X> type form allows typed positional access, but based on the explicitly supplied type which the tuple value must be type-assignable to.

aliased

Allows access to the underlying tuple values based an (optionally) assigned alias. The example query did not apply an alias. An alias would be applied via the alias method on javax.persistence.criteria.Selection. Just like positional access, there is both a typed (Object get(String alias)) and an untyped (<X> X get(String alias, Class<X> type form.

 

A CriteriaQuery object defines a query over one or more entity, embeddable, or basic abstract schema types. The root objects of the query are entities, from which the other types are reached by navigation.

 
 --JPA Specification, section 6.5.2 Query Roots, pg 262

Note

All the individual parts of the FROM clause (roots, joins, paths) implement the javax.persistence.criteria.From interface.

Note

Roots, joins and fetches are themselves paths as well.


Use the parameter method of javax.persistence.criteria.CriteriaBuilder to obtain a parameter reference. Then use the parameter reference to bind the parameter value to the javax.persistence.Query