ObjectDB ObjectDB

JPA Criteria API Queries

The JPA Criteria API provides an alternative way for defining JPA queries, which is mainly useful for building dynamic queries whose exact structure is only known at runtime.

JPA Criteria API vs JPQL

JPQL queries are defined as strings, similarly to SQL. JPA criteria queries, on the other hand, are defined by the instantiation of Java objects that represent query elements.

A major advantage of using the criteria API is that errors can be detected earlier, during compilation rather than at runtime. On the other hand, for many developers string based JPQL queries, which are very similar to SQL queries, are easier to use and understand.

For simple static queries - string based JPQL queries (e.g. as named queries) may be preferred. For dynamic queries that are built at runtime - the criteria API may be preferred.

For example, building a dynamic query based on fields that a user fills at runtime in a form that contains many optional fields - is expected to be cleaner when using the JPA criteria API, because it eliminates the need for building the query using many string concatenation operations.

String based JPQL queries and JPA criteria based queries are equally powerful and efficient. Therefore, choosing one method over the other is also a matter of personal preference. 

First JPA Criteria Query

The following query string represents a minimal JPQL query:

SELECT c FROM Country c

An equivalent query can be built using the JPA criteria API as follows:

  CriteriaBuilderjavax.persistence.criteria.CriteriaBuilderJPA interfaceUsed to construct criteria queries, compound selections, 
 expressions, predicates, orderings.See JavaDoc Reference Page... cb = em.getCriteriaBuildergetCriteriaBuilder()EntityManager's methodReturn an instance of CriteriaBuilder for the creation of
 CriteriaQuery objects.See JavaDoc Reference Page...();

  CriteriaQueryjavax.persistence.criteria.CriteriaQueryJPA interfaceThe CriteriaQuery interface defines functionality that is specific 
 to top-level queries.See JavaDoc Reference Page...<Country> q = cb.createQuerycreateQuery(resultClass)CriteriaBuilder's methodCreate a CriteriaQuery object with the specified result 
  type.See JavaDoc Reference Page...(Country.class);
  Rootjavax.persistence.criteria.RootJPA interfaceA root type in the from clause.See JavaDoc Reference Page...<Country> c = q.fromfrom(entityClass)AbstractQuery's methodCreate and add a query root corresponding to the given entity,
 forming a cartesian product with any existing roots.See JavaDoc Reference Page...(Country.class);
  q.selectselect(selection)CriteriaQuery's methodSpecify the item that is to be returned in the query result.See JavaDoc Reference Page...(c);

The CriteriaBuilderjavax.persistence.criteria.CriteriaBuilderJPA interfaceUsed to construct criteria queries, compound selections, expressions, predicates, orderings.See JavaDoc Reference Page... interface serves as the main factory of criteria queries and criteria query elements. It can be obtained either by the EntityManagerFactoryjavax.persistence.EntityManagerFactoryJPA interfaceInterface used to interact with the entity manager factory for the persistence unit.See JavaDoc Reference Page...'s getCriteriaBuildergetCriteriaBuilder()EntityManagerFactory's methodReturn an instance of CriteriaBuilder for the creation of CriteriaQuery objects.See JavaDoc Reference Page... method or by the EntityManagerjavax.persistence.EntityManagerJPA interfaceInterface used to interact with the persistence context.See JavaDoc Reference Page...'s getCriteriaBuildergetCriteriaBuilder()EntityManager's methodReturn an instance of CriteriaBuilder for the creation of CriteriaQuery objects.See JavaDoc Reference Page... method (both methods are equivalent).

In the example above a CriteriaQueryjavax.persistence.criteria.CriteriaQueryJPA interfaceThe CriteriaQuery interface defines functionality that is specific to top-level queries.See JavaDoc Reference Page... instance is created for representing the built query. Then a Rootjavax.persistence.criteria.RootJPA interfaceA root type in the from clause.See JavaDoc Reference Page... instance is created to define a range variable in the FROM clause. Finally, the range variable, c, is also used in the SELECT clause as the query result expression.

CriteriaQuery instance is equivalent to a JPQL string and not to a TypedQueryjavax.persistence.TypedQueryJPA interfaceInterface used to control the execution of typed queries.See JavaDoc Reference Page... instance. Therefore, running the query still requires a TypedQuery instance:

  TypedQueryjavax.persistence.TypedQueryJPA interfaceInterface used to control the execution of typed queries.See JavaDoc Reference Page...<Country> query = em.createQuerycreateQuery(criteriaQuery)EntityManager's methodCreate an instance of TypedQuery for executing a
 criteria query.See JavaDoc Reference Page...(q);
  List<Country> results = query.getResultListgetResultList()Query's methodExecute a SELECT query and return the query results
 as an untyped List.See JavaDoc Reference Page...();

Using the criteria API introduces some extra work, at least for simple static queries, since the equivalent JPQL query could simply be executed as follows:

  TypedQueryjavax.persistence.TypedQueryJPA interfaceInterface used to control the execution of typed queries.See JavaDoc Reference Page...<Country> query =
      em.createQuerycreateQuery(qlString, resultClass)EntityManager's methodCreate an instance of TypedQuery for executing a
 Java Persistence query language statement.See JavaDoc Reference Page...("SELECT c FROM Country c", Country.class);
  List<Country> results = query.getResultListgetResultList()Query's methodExecute a SELECT query and return the query results
 as an untyped List.See JavaDoc Reference Page...();

Because eventually both types of queries are represented by a TypedQueryjavax.persistence.TypedQueryJPA interfaceInterface used to control the execution of typed queries.See JavaDoc Reference Page... instance - query execution and query setting is similar, regardless of the way in which the query is built.

Parameters in Criteria Queries

The following query string represents a JPQL query with a parameter:

SELECT c FROM Country c WHERE c.population > :p

An equivalent query can be built using the JPA criteria API as follows:

  CriteriaBuilderjavax.persistence.criteria.CriteriaBuilderJPA interfaceUsed to construct criteria queries, compound selections, 
 expressions, predicates, orderings.See JavaDoc Reference Page... cb = em.getCriteriaBuildergetCriteriaBuilder()EntityManager's methodReturn an instance of CriteriaBuilder for the creation of
 CriteriaQuery objects.See JavaDoc Reference Page...();

  CriteriaQueryjavax.persistence.criteria.CriteriaQueryJPA interfaceThe CriteriaQuery interface defines functionality that is specific 
 to top-level queries.See JavaDoc Reference Page...<Country> q = cb.createQuerycreateQuery(resultClass)CriteriaBuilder's methodCreate a CriteriaQuery object with the specified result 
  type.See JavaDoc Reference Page...(Country.class);
  Rootjavax.persistence.criteria.RootJPA interfaceA root type in the from clause.See JavaDoc Reference Page...<Country> c = q.fromfrom(entityClass)AbstractQuery's methodCreate and add a query root corresponding to the given entity,
 forming a cartesian product with any existing roots.See JavaDoc Reference Page...(Country.class);
  ParameterExpressionjavax.persistence.criteria.ParameterExpressionJPA interfaceType of criteria query parameter expressions.See JavaDoc Reference Page...<Integer> p = cb.parameterparameter(paramClass)CriteriaBuilder's methodCreate a parameter expression.See JavaDoc Reference Page...(Integer.class);
  q.selectselect(selection)CriteriaQuery's methodSpecify the item that is to be returned in the query result.See JavaDoc Reference Page...(c).wherewhere(restriction)CriteriaQuery's methodModify the query to restrict the query result according
 to the specified boolean expression.See JavaDoc Reference Page...(cb.gtgt(x, y)CriteriaBuilder's methodCreate a predicate for testing whether the first argument is 
 greater than the second.See JavaDoc Reference Page...(c.getget(attributeName)Path's methodCreate a path corresponding to the referenced attribute.See JavaDoc Reference Page...("population"), p));

The ParameterExpressionjavax.persistence.criteria.ParameterExpressionJPA interfaceType of criteria query parameter expressions.See JavaDoc Reference Page... instance, p, is created to represent the query parameter. The wherewhere(restriction)CriteriaQuery's methodModify the query to restrict the query result according to the specified boolean expression.See JavaDoc Reference Page... method sets the WHERE clause. As shown above, The CriteriaQueryjavax.persistence.criteria.CriteriaQueryJPA interfaceThe CriteriaQuery interface defines functionality that is specific to top-level queries.See JavaDoc Reference Page... interface supports method chaining. See the links in the next sections of this page for detailed explanations on how to set criteria query clauses and build criteria expressions.

Running this query requires setting the parameter:

  TypedQueryjavax.persistence.TypedQueryJPA interfaceInterface used to control the execution of typed queries.See JavaDoc Reference Page...<Country> query = em.createQuerycreateQuery(criteriaQuery)EntityManager's methodCreate an instance of TypedQuery for executing a
 criteria query.See JavaDoc Reference Page...(q);
  query.setParametersetParameter(param, value)Query's methodBind the value of a Parameter object.See JavaDoc Reference Page...(p, 10000000);
  List<Country> results = query.getResultListgetResultList()Query's methodExecute a SELECT query and return the query results
 as an untyped List.See JavaDoc Reference Page...();

The setParametersetParameter(param, value)Query's methodBind the value of a Parameter object.See JavaDoc Reference Page... method takes a Parameterjavax.persistence.ParameterJPA interfaceType for query parameter objects.See JavaDoc Reference Page... (or a ParameterExpressionjavax.persistence.criteria.ParameterExpressionJPA interfaceType of criteria query parameter expressions.See JavaDoc Reference Page...) instance as the first argument instead of a name or a position (which are used with string based JPQL parameters).

Criteria Query Structure

Queries in JPA (as in SQL) are composed of clauses. Because JPQL queries and criteria queries use equivalent clauses - they are explained side by side in the Query Structure pages.

Specific details about criteria query clauses are provided in the following page sections:

The links above are direct links to the criteria query sections in pages that describe query structure in general, including in the context of string based JPQL queries.

Criteria Query Expressions

JPA query clauses are composed of expressions. Because JPQL queries and criteria queries use equivalent expressions - they are explained side by side in the Query Expressions pages.

Specific details about criteria query expressions are provided in the following page sections:

The links above are direct links to the criteria query sections in pages that describe expressions in general, including in the context of string based JPQL queries.