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.
This page covers the following topics:
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.CriteriaBuilder - JPA InterfaceUsed to construct criteria queries, compound selections, expressions, predicates, orderings. cb = em.getCriteriaBuilderEntityManager.getCriteriaBuilder() - JPA MethodReturn an instance ofCriteriaBuilder
for the creation ofCriteriaQuery
objects.(); CriteriaQueryjavax.persistence.criteria.CriteriaQuery- JPA Interface TheCriteriaQuery
interface defines functionality that is specific to top-level queries.<Country> q = cb.createQueryCriteriaBuilder.createQuery(resultClass) - JPA MethodCreate aCriteriaQuery
object with the specified result type.(Country.class); Rootjavax.persistence.criteria.Root- JPA Interface A root type in the from clause.<Country> c = q.fromAbstractQuery.from(entityClass) - JPA Method Create and add a query root corresponding to the given entity, forming a cartesian product with any existing roots.(Country.class); q.selectCriteriaQuery.select(selection) - JPA MethodSpecify the item that is to be returned in the query result.(c);
The CriteriaBuilder
javax.persistence.criteria.CriteriaBuilder - JPA InterfaceUsed to construct criteria queries, compound selections, expressions, predicates, orderings. interface serves as the main factory of criteria queries and criteria query elements. It can be obtained either by the EntityManagerFactory
javax.persistence.EntityManagerFactory - JPA InterfaceInterface used to interact with the entity manager factory for the persistence unit.'s getCriteriaBuilder
EntityManagerFactory.getCriteriaBuilder() - JPA MethodReturn an instance of CriteriaBuilder
for the creation of CriteriaQuery
objects. method or by the EntityManager
javax.persistence.EntityManager - JPA InterfaceInterface used to interact with the persistence context.'s getCriteriaBuilder
EntityManager.getCriteriaBuilder() - JPA MethodReturn an instance of CriteriaBuilder
for the creation of CriteriaQuery
objects. method (both methods are equivalent).
In the example above a CriteriaQuery
javax.persistence.criteria.CriteriaQueryCriteriaQuery
interface defines functionality that is specific to top-level queries. instance is created for representing the built query. Then a Root
javax.persistence.criteria.Rootc
, is also used in the SELECT clause as the query result expression.
A CriteriaQuery
instance is equivalent to a JPQL string and not to a TypedQuery
javax.persistence.TypedQueryTypedQuery
instance:
TypedQueryjavax.persistence.TypedQuery- JPA Interface Interface used to control the execution of typed queries.<Country> query = em.createQueryEntityManager.createQuery(criteriaQuery) - JPA MethodCreate an instance ofTypedQuery
for executing a criteria query.(q); List<Country> results = query.getResultListQuery.getResultList() - JPA MethodExecute a SELECT query and return the query results as an untyped List.();
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.TypedQuery- JPA Interface Interface used to control the execution of typed queries.<Country> query = em.createQueryEntityManager.createQuery(qlString,resultClass) - JPA MethodCreate an instance ofTypedQuery
for executing a Java Persistence query language statement.("SELECT c FROM Country c", Country.class); List<Country> results = query.getResultListQuery.getResultList() - JPA MethodExecute a SELECT query and return the query results as an untyped List.();
Because eventually both types of queries are represented by a TypedQuery
javax.persistence.TypedQuery
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.CriteriaBuilder - JPA InterfaceUsed to construct criteria queries, compound selections, expressions, predicates, orderings. cb = em.getCriteriaBuilderEntityManager.getCriteriaBuilder() - JPA MethodReturn an instance ofCriteriaBuilder
for the creation ofCriteriaQuery
objects.(); CriteriaQueryjavax.persistence.criteria.CriteriaQuery- JPA Interface TheCriteriaQuery
interface defines functionality that is specific to top-level queries.<Country> q = cb.createQueryCriteriaBuilder.createQuery(resultClass) - JPA MethodCreate aCriteriaQuery
object with the specified result type.(Country.class); Rootjavax.persistence.criteria.Root- JPA Interface A root type in the from clause.<Country> c = q.fromAbstractQuery.from(entityClass) - JPA Method Create and add a query root corresponding to the given entity, forming a cartesian product with any existing roots.(Country.class); ParameterExpressionjavax.persistence.criteria.ParameterExpression- JPA Interface Type of criteria query parameter expressions.<Integer> p = cb.parameterCriteriaBuilder.parameter(paramClass) - JPA MethodCreate a parameter expression.(Integer.class); q.selectCriteriaQuery.select(selection) - JPA MethodSpecify the item that is to be returned in the query result.(c).whereCriteriaQuery.where(restriction) - JPA MethodModify the query to restrict the query result according to the specified boolean expression.(cb.gtCriteriaBuilder.gt(x,y) - JPA MethodCreate a predicate for testing whether the first argument is greater than the second.(c.getPath.get(attributeName) - JPA Method Create a path corresponding to the referenced attribute.("population"), p));
The ParameterExpression
javax.persistence.criteria.ParameterExpressionp
, is created to represent the query parameter. The whereCriteriaQuery.where(restriction) - JPA MethodModify the query to restrict the query result according to the specified boolean expression. method sets the WHERE clause. As shown above, The CriteriaQuery
javax.persistence.criteria.CriteriaQueryCriteriaQuery
interface defines functionality that is specific to top-level queries. 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.TypedQuery- JPA Interface Interface used to control the execution of typed queries.<Country> query = em.createQueryEntityManager.createQuery(criteriaQuery) - JPA MethodCreate an instance ofTypedQuery
for executing a criteria query.(q); query.setParameterQuery.setParameter(param,value) - JPA MethodBind the value of aParameter
object.(p, 10000000); List<Country> results = query.getResultListQuery.getResultList() - JPA MethodExecute a SELECT query and return the query results as an untyped List.();
The setParameter
Query.setParameter(param,value) - JPA MethodBind the value of a Parameter
object. method takes a Parameter
javax.persistence.ParameterParameterExpression
javax.persistence.criteria.ParameterExpression
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:
- SELECT clause (
select
CriteriaQuery.select(selection) - JPA MethodSpecify the item that is to be returned in the query result.,distinct
CriteriaQuery.distinct(distinct) - JPA MethodSpecify whether duplicate query results will be eliminated.,multiselect
CriteriaQuery.multiselect(selections) - JPA MethodSpecify the selection items that are to be returned in the query result.,array
CriteriaBuilder.array(selections) - JPA MethodCreate an array-valued selection item.,tuple
CriteriaBuilder.tuple(selections) - JPA MethodCreate a tuple-valued selection item.,construct
CriteriaBuilder.construct(resultClass,selections) - JPA MethodCreate a selection item corresponding to a constructor.). - FROM clause (
from
AbstractQuery.from(entityClass) - JPA Method Create and add a query root corresponding to the given entity, forming a cartesian product with any existing roots.,join
From.join(attributeName,jt) - JPA Method Create a join to the specified attribute using the given join type.,fetch
FetchParent.fetch(attributeName) - JPA MethodCreate a fetch join to the specified attribute using an inner join.). - WHERE clause (
where
CriteriaQuery.where(restrictions) - JPA MethodModify the query to restrict the query result according to the conjunction of the specified restriction predicates.). - GROUP BY / HAVING clauses (
groupBy
CriteriaQuery.groupBy(grouping) - JPA MethodSpecify the expressions that are used to form groups over the query results.,having
CriteriaQuery.having(restriction) - JPA MethodSpecify a restriction over the groups of the query.,count
CriteriaBuilder.count(x) - JPA MethodCreate an aggregate expression applying the count operation.,sum
CriteriaBuilder.sum(x) - JPA MethodCreate an aggregate expression applying the sum operation.,avg
CriteriaBuilder.avg(x) - JPA MethodCreate an aggregate expression applying the avg operation.,min
CriteriaBuilder.min(x) - JPA MethodCreate an aggregate expression applying the numerical min operation.,max
CriteriaBuilder.max(x) - JPA MethodCreate an aggregate expression applying the numerical max operation., ...). - ORDER BY clause (
orderBy
CriteriaQuery.orderBy(o) - JPA MethodSpecify the ordering expressions that are used to order the query results.,Order
javax.persistence.criteria.Order - JPA InterfaceAn object that defines an ordering over the query results.,asc
CriteriaBuilder.asc(x) - JPA MethodCreate an ordering by the ascending value of the expression.,desc
CriteriaBuilder.desc(x) - JPA MethodCreate an ordering by the descending value of the expression.).
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:
- Literals and Dates (
literalCriteriaBuilder.literal(value) - JPA MethodCreate an expression for a literal.
,nullLiteral
CriteriaBuilder.nullLiteral(resultClass) - JPA MethodCreate an expression for a null literal with the given type.,currentDate
CriteriaBuilder.currentDate() - JPA MethodCreate expression to return current date., ...). - Paths, navigation and types (
getPath
,.get(attributeName) - JPA Method Create a path corresponding to the referenced attribute.type
Path.type() - JPA Method Create an expression corresponding to the type of the path.). - Arithmetic expressions (
sum
CriteriaBuilder.sum(x,y) - JPA MethodCreate an expression that returns the sum of its arguments.,diff
CriteriaBuilder.diff(x,y) - JPA MethodCreate an expression that returns the difference between its arguments.,prod
CriteriaBuilder.prod(x,y) - JPA MethodCreate an expression that returns the product of its arguments.,quot
CriteriaBuilder.quot(x,y) - JPA MethodCreate an expression that returns the quotient of its arguments.,mod
CriteriaBuilder.mod(x,y) - JPA MethodCreate an expression that returns the modulus of its arguments.,abs
CriteriaBuilder.abs(x) - JPA MethodCreate an expression that returns the absolute value of its argument.,neg
CriteriaBuilder.neg(x) - JPA MethodCreate an expression that returns the arithmetic negation of its argument.,sqrt
CriteriaBuilder.sqrt(x) - JPA MethodCreate an expression that returns the square root of its argument.). - String expressions (
like
CriteriaBuilder.like(x,pattern) - JPA MethodCreate a predicate for testing whether the expression satisfies the given pattern.,length
CriteriaBuilder.length(x) - JPA MethodCreate expression to return length of a string.,locate
CriteriaBuilder.locate(x,pattern) - JPA MethodCreate expression to locate the position of one string within another, returning position of first character if found.,lower
CriteriaBuilder.lower(x) - JPA MethodCreate expression for converting a string to lowercase.,upper
CriteriaBuilder.upper(x) - JPA MethodCreate expression for converting a string to uppercase.,concat
CriteriaBuilder.concat(x,y) - JPA MethodCreate an expression for string concatenation.,substringCriteriaBuilder.substring(x,from) - JPA MethodCreate an expression for substring extraction., ...
). - Collection expressions (
isEmpty
CriteriaBuilder.isEmpty(collection) - JPA MethodCreate a predicate that tests whether a collection is empty.,isNotEmpty
CriteriaBuilder.isNotEmpty(collection) - JPA MethodCreate a predicate that tests whether a collection is not empty.,isMember
CriteriaBuilder.isMember(elem,collection) - JPA MethodCreate a predicate that tests whether an element is a member of a collection.,isNotMember
CriteriaBuilder.isNotMember(elem,collection) - JPA MethodCreate a predicate that tests whether an element is not a member of a collection.,size
CriteriaBuilder.size(collection) - JPA MethodCreate an expression that tests the size of a collection.). - Comparison expressions (
equal
CriteriaBuilder.size(collection) - JPA MethodCreate an expression that tests the size of a collection.,notEqual
CriteriaBuilder.notEqual(x,y) - JPA MethodCreate a predicate for testing the arguments for inequality.,gt
CriteriaBuilder.gt(x,y) - JPA MethodCreate a predicate for testing whether the first argument is greater than the second.,ge
CriteriaBuilder.ge(x,y) - JPA MethodCreate a predicate for testing whether the first argument is greater than or equal to the second.,lt
CriteriaBuilder.lt(x,y) - JPA MethodCreate a predicate for testing whether the first argument is less than the second.,le
CriteriaBuilder.le(x,y) - JPA MethodCreate a predicate for testing whether the first argument is less than or equal to the second.,between
CriteriaBuilder.between(v,x,y) - JPA MethodCreate a predicate for testing whether the first argument is between the second and third arguments in value.,isNull
CriteriaBuilder.isNull(x) - JPA MethodCreate a predicate to test whether the expression is null., ...) - Logical expressions (
and
CriteriaBuilder.and(x,y) - JPA MethodCreate a conjunction of the given boolean expressions.,or
CriteriaBuilder.or(x,y) - JPA MethodCreate a disjunction of the given boolean expressions.,not
CriteriaBuilder.not(restriction) - JPA MethodCreate a negation of the given restriction.,isTrue
CriteriaBuilder.isTrue(x) - JPA MethodCreate a predicate testing for a true value.).
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.