JPA Criteria API Queries
The JPA Criteria API provides an alternative way to define JPA queries. It is useful for building dynamic queries whose structure is known only at runtime.
This page covers the following topics:
JPA Criteria API vs. JPQLFirst JPA Criteria queryParameters in Criteria queriesCriteria query structureCriteria query expressions
JPA Criteria API vs. JPQL
JPQL queries are defined as strings, similar to SQL. In contrast, JPA Criteria queries are defined by instantiating Java objects that represent query elements.
A major advantage of the Criteria API is that it enables compile-time error checking. Errors in string-based JPQL queries, however, are found at runtime. Many developers find string-based JPQL queries easier to use and understand because of their similarity to SQL.
String-based JPQL queries, such as named queries, are often preferred for simple, static queries. The Criteria API is generally better for dynamic queries that are built at runtime.
For example, building a dynamic query based on a form with many optional fields is cleaner with the Criteria API because it avoids complex string concatenation.
String-based JPQL queries and JPA Criteria-based queries are equally powerful and efficient. Therefore, the choice between them can also be a matter of personal preference.
First JPA Criteria query
The following string is a minimal JPQL query:
SELECT c FROM Country c
You can build an equivalent query with the JPA Criteria API as follows:
CriteriaBuilderjakarta.persistence.criteria.CriteriaBuilderUsed to construct criteria queries, compound selections, expressions, predicates, orderings. cb = em.getCriteriaBuilderjakarta.persistence.EntityManager.getCriteriaBuilder()Obtain an instance of CriteriaBuilder which may be used to construct CriteriaQuery<T> objects.(); CriteriaQueryjakarta.persistence.criteria.CriteriaQueryThe CriteriaQuery interface defines functionality that is specific to top-level queries.<Country> q = cb.createQueryjakarta.persistence.criteria.CriteriaBuilder.createQuery(Class)Create a CriteriaQuery<T> object with the given result type.(Country.class); Rootjakarta.persistence.criteria.RootA root type in the from clause.<Country> c = q.fromjakarta.persistence.criteria.AbstractQuery.from(Class)Create and add a query root corresponding to the given entity, forming a cartesian product with any existing roots.(Country.class); q.selectjakarta.persistence.criteria.CriteriaQuery.select(Selection)Specify the item that is to be returned in the query result.(c);
The CriteriaBuilderjakarta.persistence.criteria.CriteriaBuilderUsed to construct criteria queries, compound selections, expressions, predicates, orderings. interface is the main factory for Criteria queries and their elements. You can get an instance from either the EntityManagerFactoryjakarta.persistence.EntityManagerFactoryInterface used to interact with the persistence unit, and to create new instances of EntityManager .'s getCriteriaBuilderjakarta.persistence.EntityManagerFactory.getCriteriaBuilder()Return an instance of CriteriaBuilder which may be used to construct CriteriaQuery<T> objects. method or the EntityManagerjakarta.persistence.EntityManagerInterface used to interact with the persistence context.'s getCriteriaBuilderjakarta.persistence.EntityManager.getCriteriaBuilder()Obtain an instance of CriteriaBuilder which may be used to construct CriteriaQuery<T> objects. method.
In the example, a CriteriaQueryjakarta.persistence.criteria.CriteriaQueryThe CriteriaQuery interface defines functionality that is specific to top-level queries. instance is created to represent the query. A Rootjakarta.persistence.criteria.RootA root type in the from clause. instance defines the FROM clause's range variable. Finally, the range variable, c, is used in the SELECT clause as the query's result expression.
After building the CriteriaQuery, you use it to create a TypedQueryjakarta.persistence.TypedQueryInterface used to control the execution of typed queries. object, which you can then execute:
TypedQueryjakarta.persistence.TypedQueryInterface used to control the execution of typed queries.<Country> query = em.createQueryjakarta.persistence.EntityManager.createQuery(CriteriaQuery)Create an instance of TypedQuery<X> for executing a criteria query.(q); List<Country> results = query.getResultListjakarta.persistence.Query.getResultList()Execute a SELECT query and return the query results as an untyped List<E> .();
The Criteria API requires more code, especially for simple static queries. The equivalent JPQL query can be executed more concisely:
TypedQueryjakarta.persistence.TypedQueryInterface used to control the execution of typed queries.<Country> query = em.createQueryjakarta.persistence.EntityManager.createQuery(String,Class)Create an instance of TypedQuery<X> for executing a Jakarta Persistence query language statement.("SELECT c FROM Country c", Country.class); List<Country> results = query.getResultListjakarta.persistence.Query.getResultList()Execute a SELECT query and return the query results as an untyped List<E> .();
Because both types of queries are ultimately represented by a TypedQueryjakarta.persistence.TypedQueryInterface used to control the execution of typed queries. instance, query execution and settings are similar, regardless of how the query is built.
Parameters in Criteria queries
The following string is a JPQL query with a parameter:
SELECT c FROM Country c WHERE c.population > :p
You can build an equivalent query with the JPA Criteria API as follows:
CriteriaBuilderjakarta.persistence.criteria.CriteriaBuilderUsed to construct criteria queries, compound selections, expressions, predicates, orderings. cb = em.getCriteriaBuilderjakarta.persistence.EntityManager.getCriteriaBuilder()Obtain an instance of CriteriaBuilder which may be used to construct CriteriaQuery<T> objects.(); CriteriaQueryjakarta.persistence.criteria.CriteriaQueryThe CriteriaQuery interface defines functionality that is specific to top-level queries.<Country> q = cb.createQueryjakarta.persistence.criteria.CriteriaBuilder.createQuery(Class)Create a CriteriaQuery<T> object with the given result type.(Country.class); Rootjakarta.persistence.criteria.RootA root type in the from clause.<Country> c = q.fromjakarta.persistence.criteria.AbstractQuery.from(Class)Create and add a query root corresponding to the given entity, forming a cartesian product with any existing roots.(Country.class); ParameterExpressionjakarta.persistence.criteria.ParameterExpressionType of criteria query parameter expressions.<Integer> p = cb.parameterjakarta.persistence.criteria.CriteriaBuilder.parameter(Class)Create a parameter expression.(Integer.class); q.selectjakarta.persistence.criteria.CriteriaQuery.select(Selection)Specify the item that is to be returned in the query result.(c).wherejakarta.persistence.criteria.CriteriaQuery.where(Expression)Modify the query to restrict the query result according to the specified boolean expression.(cb.gtjakarta.persistence.criteria.CriteriaBuilder.gt(Expression,Expression)Create a predicate for testing whether the first argument is greater than the second.(c.getjakarta.persistence.criteria.Path.get(String)Create a path corresponding to the referenced attribute.("population"), p));
The p ParameterExpressionjakarta.persistence.criteria.ParameterExpressionType of criteria query parameter expressions. instance represents the query parameter. The wherejakarta.persistence.criteria.CriteriaQuery.where(Expression)Modify the query to restrict the query result according to the specified boolean expression. method sets the WHERE clause. As shown, the CriteriaQueryjakarta.persistence.criteria.CriteriaQueryThe CriteriaQuery interface defines functionality that is specific to top-level queries. interface supports method chaining. For details on setting clauses and building expressions, see the links in the following sections.
To run this query, you must set the parameter value:
TypedQueryjakarta.persistence.TypedQueryInterface used to control the execution of typed queries.<Country> query = em.createQueryjakarta.persistence.EntityManager.createQuery(CriteriaQuery)Create an instance of TypedQuery<X> for executing a criteria query.(q); query.setParameterjakarta.persistence.Query.setParameter(Parameter,T)Bind the value of a Parameter object.(p, 10000000); List<Country> results = query.getResultListjakarta.persistence.Query.getResultList()Execute a SELECT query and return the query results as an untyped List<E> .();
The setParameterjakarta.persistence.Query.setParameter(Parameter,T)Bind the value of a Parameter object. method takes a Parameterjakarta.persistence.ParameterType for query parameter objects. instance (such as a ParameterExpressionjakarta.persistence.criteria.ParameterExpressionType of criteria query parameter expressions.) as its first argument. This differs from string-based JPQL parameters, which use a name or position.
Criteria query structure
JPA queries, like SQL queries, consist of clauses. Because JPQL and Criteria queries use equivalent clauses, this guide explains them side-by-side in the Query Structure pages.
The following sections provide specific details about Criteria query clauses:
SELECTclause (selectjakarta.persistence.criteria.CriteriaQuery.select(Selection)Specify the item that is to be returned in the query result.,distinctjakarta.persistence.criteria.CriteriaQuery.distinct(boolean)Specify whether duplicate query results are eliminated.,multiselectjakarta.persistence.criteria.CriteriaQuery.multiselect(Selection...)Specify the selection items that are to be returned in the query result.,arrayjakarta.persistence.criteria.CriteriaBuilder.array(Selection...)Create an array-valued selection item.,tuplejakarta.persistence.criteria.CriteriaBuilder.tuple(Selection...)Create a tuple-valued selection item.,constructjakarta.persistence.criteria.CriteriaBuilder.construct(Class,Selection...)Create a selection item corresponding to a constructor.)FROMclause (fromjakarta.persistence.criteria.AbstractQuery.from(Class)Create and add a query root corresponding to the given entity, forming a cartesian product with any existing roots.,joinjakarta.persistence.criteria.From.join(String,JoinType)Create a join to the specified attribute using the given join type.,fetchjakarta.persistence.criteria.FetchParent.fetch(String)Create a fetch join to the specified attribute using an inner join.)WHEREclause (wherejakarta.persistence.criteria.CriteriaQuery.where(Predicate...)Modify the query to restrict the query result according to the conjunction of the specified restriction predicates.)GROUP BYandHAVINGclauses (groupByjakarta.persistence.criteria.CriteriaQuery.groupBy(Expression...)Specify the expressions that are used to form groups over the query results.,havingjakarta.persistence.criteria.CriteriaQuery.having(Expression)Specify a restriction over the groups of the query.,countjakarta.persistence.criteria.CriteriaBuilder.count(Expression)Create an aggregate expression applying the count operation.,sumjakarta.persistence.criteria.CriteriaBuilder.sum(Expression)Create an aggregate expression applying the sum operation.,avgjakarta.persistence.criteria.CriteriaBuilder.avg(Expression)Create an aggregate expression applying the avg operation.,minjakarta.persistence.criteria.CriteriaBuilder.min(Expression)Create an aggregate expression applying the numerical min operation.,maxjakarta.persistence.criteria.CriteriaBuilder.max(Expression)Create an aggregate expression applying the numerical max operation., ...)ORDER BYclause (orderByjakarta.persistence.criteria.CriteriaQuery.orderBy(Order...)Specify the ordering expressions that are used to order the query results.,Orderjakarta.persistence.criteria.OrderAn object that defines an ordering over the query results.,ascjakarta.persistence.criteria.CriteriaBuilder.asc(Expression)Create an ordering by the ascending value of the expression.,descjakarta.persistence.criteria.CriteriaBuilder.desc(Expression)Create an ordering by the descending value of the expression.)
The links above go to the Criteria query sections within pages that also cover string-based JPQL queries.
Criteria query expressions
JPA query clauses consist of expressions. Because JPQL and Criteria queries use equivalent expressions, this guide explains them side-by-side in the Query Expressions pages.
The following sections provide specific details about Criteria query expressions:
- Literals and dates (
literaljakarta.persistence.criteria.CriteriaBuilder.literal(T)Create an expression for a literal.,nullLiteraljakarta.persistence.criteria.CriteriaBuilder.nullLiteral(Class)Create an expression for a null literal with the given type.,currentDatejakarta.persistence.criteria.CriteriaBuilder.currentDate()Create expression to return current date., ...) - Paths, navigation, and types (
getjakarta.persistence.criteria.Path.get(String)Create a path corresponding to the referenced attribute.,typejakarta.persistence.criteria.Path.type()Create an expression corresponding to the type of the path.) - Arithmetic expressions (
sumjakarta.persistence.criteria.CriteriaBuilder.sum(Expression,Expression)Create an expression that returns the sum of its arguments.,diffjakarta.persistence.criteria.CriteriaBuilder.diff(Expression,Expression)Create an expression that returns the difference between its arguments.,prodjakarta.persistence.criteria.CriteriaBuilder.prod(Expression,Expression)Create an expression that returns the product of its arguments.,quotjakarta.persistence.criteria.CriteriaBuilder.quot(Expression,Expression)Create an expression that returns the quotient of its arguments.,modjakarta.persistence.criteria.CriteriaBuilder.mod(Expression,Expression)Create an expression that returns the modulus (remainder under integer division) of its arguments.,absjakarta.persistence.criteria.CriteriaBuilder.abs(Expression)Create an expression that returns the absolute value of its argument.,negjakarta.persistence.criteria.CriteriaBuilder.neg(Expression)Create an expression that returns the arithmetic negation of its argument.,sqrtjakarta.persistence.criteria.CriteriaBuilder.sqrt(Expression)Create an expression that returns the square root of its argument.) - String expressions (
likejakarta.persistence.criteria.CriteriaBuilder.like(Expression,Expression)Create a predicate for testing whether the expression satisfies the given pattern.,lengthjakarta.persistence.criteria.CriteriaBuilder.length(Expression)Create expression to return length of a string.,locatejakarta.persistence.criteria.CriteriaBuilder.locate(Expression,Expression)Create expression to locate the position of one string within another, returning position of first character if found.,lowerjakarta.persistence.criteria.CriteriaBuilder.lower(Expression)Create expression for converting a string to lowercase.,upperjakarta.persistence.criteria.CriteriaBuilder.upper(Expression)Create expression for converting a string to uppercase.,concatjakarta.persistence.criteria.CriteriaBuilder.concat(Expression,Expression)Create an expression for string concatenation.,substringjakarta.persistence.criteria.CriteriaBuilder.substring(Expression,Expression)Create an expression for substring extraction., ...) - Collection expressions (
isEmptyjakarta.persistence.criteria.CriteriaBuilder.isEmpty(Expression)Create a predicate that tests whether a collection is empty.,isNotEmptyjakarta.persistence.criteria.CriteriaBuilder.isNotEmpty(Expression)Create a predicate that tests whether a collection is not empty.,isMemberjakarta.persistence.criteria.CriteriaBuilder.isMember(Expression,Expression)Create a predicate that tests whether an element is a member of a collection.,isNotMemberjakarta.persistence.criteria.CriteriaBuilder.isNotMember(Expression,Expression)Create a predicate that tests whether an element is not a member of a collection.,sizejakarta.persistence.criteria.CriteriaBuilder.size(Expression)Create an expression that tests the size of a collection.) - Comparison expressions (
equaljakarta.persistence.criteria.CriteriaBuilder.size(Expression)Create an expression that tests the size of a collection.,notEqualjakarta.persistence.criteria.CriteriaBuilder.notEqual(Expression,Expression)Create a predicate for testing the arguments for inequality.,gtjakarta.persistence.criteria.CriteriaBuilder.gt(Expression,Expression)Create a predicate for testing whether the first argument is greater than the second.,gejakarta.persistence.criteria.CriteriaBuilder.ge(Expression,Expression)Create a predicate for testing whether the first argument is greater than or equal to the second.,ltjakarta.persistence.criteria.CriteriaBuilder.lt(Expression,Expression)Create a predicate for testing whether the first argument is less than the second.,lejakarta.persistence.criteria.CriteriaBuilder.le(Expression,Expression)Create a predicate for testing whether the first argument is less than or equal to the second.,betweenjakarta.persistence.criteria.CriteriaBuilder.between(Expression,Expression,Expression)Create a predicate for testing whether the first argument is between the second and third arguments in value.,isNulljakarta.persistence.criteria.CriteriaBuilder.isNull(Expression)Create a predicate to test whether the expression is null., ...) - Logical expressions (
andjakarta.persistence.criteria.CriteriaBuilder.and(Expression,Expression)Create a conjunction of the given boolean expressions.,orjakarta.persistence.criteria.CriteriaBuilder.or(Expression,Expression)Create a disjunction of the given boolean expressions.,notjakarta.persistence.criteria.CriteriaBuilder.not(Expression)Create a negation of the given restriction.,isTruejakarta.persistence.criteria.CriteriaBuilder.isTrue(Expression)Create a predicate testing for a true value.)
The links above go to the Criteria query sections within pages that also cover string-based JPQL queries.