The Java Persistence Criteria API is used to define dynamic queries through the construction of object-based query definition objects, rather than use of the string-based approach of JPQL. The criteria API allows dynamic queries to be built programmatically offering better integration with the Java language than a string-based 4th GL approach.
The Criteria API has two modes, the type-restricted mode, and the non-typed mode. The type-restricted mode uses a set of JPA meta-model generated classes to define the query-able attributes of a class, see Metamodel. The non-typed mode uses strings to reference attributes of a class.
The criteria API is only for dynamic queries, and cannot be used in meta-data or named queries. Criteria queries are dynamic queries and do not perform as well as static named queries, or even dynamic parametrized JPQL which benefit from EclipseLink's parse cache.
For more information, see Chapter 6 "Criteria API" in the JPA Specification.
http://jcp.org/en/jsr/detail?id=317
CriteriaBuilder
is the main interface into the Criteria API. A CriteriaBuilder
is obtained from an EntityManager
or an EntityManagerFactory
using the getCriteriaBuilder()
API. CriteriaBuilder
is used to construct CriteriaQuery
objects and their expressions. The Criteria API currently only supports select queries.
CriteriaQuery
defines a database select query. A CriteriaQuery
models all of the clauses of a JPQL select query. Elements from one CriteriaQuery
cannot be used in other CriteriaQuerys
. A CriteriaQuery
is used with the EntityManager
createQuery()
API to create a JPA Query.
The where
clause is normally the main part of the query as it defines the conditions (predicates) that filter what is returned. The where
clause is defined using the where
API on CriteriaQuery
with any Predicate
objects. A Predicate
is obtained using a comparison operation, or a logical operation on CriteriaBuilder
. The isNull
, isNotNull
, and in
operations can also be called on Expression
objects. The not
operation can also be called on Predicate
objects.
Subqueries can be used in the Criteria
API in the select
, where
, order
, group
by
, or having
clauses. A subquery is created from a CriteriaQuery
using the subquery
operation. Most subquery
usage restricts the subquery to returning a single result and value, unless used with the CriteriaBuilder
exists
, all
, any
, or some
operations, or with an in
operation.
Parameters can be defined using the parameter
API on CriteriaBuilder
. JPA defines named parameters, and positional parameters. For named parameters the parameter type and name are specified. For positional parameters only the parameter type is specified. Positional parameters start at position 1
not 0
.
Several database functions are supported by the Criteria
API. All supported functions are defined on CriteriaBuilder
. Some functions may not be supported by some databases, if they are not SQL compliant, and offer no equivalent function.
The Criteria
API defines several special operations that are not database functions, but have special meaning in JPA. Some of these operations are defined on CriteriaBuilder
and some are on specific Expression interfaces.
JPA defines a meta-model that can be used at runtime to query information about the ORM mapping metadata. The meta-model includes the list of mapped attributes for a class, and their mapping types and cardinality. The meta-model can be used with the Criteria API in place of using strings to reference the class attributes.
JPA defines a set of "_
" classes ("_MyEntity.java
", for example) that are to be generated by the JPA provider, or IDE, that give compile time access to the meta-model. This allows typed static variables to be used in the Criteria API. This can reduce the occurrence of typos, or invalid queries in application code, by catching query issues at compile time, instead of during testing. It does however add complexity to the development process, as the meta-model static class needs to be generated, and be part of the development cycle.
A Tuple defines a multi-select query result. Normally an object array is returned by JPA multi-select queries, but an object array is not a very useful data structure. A Tuple is a map-like structure that allows the results to be retrieved by name or index.
EclipseLink's Criteria
API support has fewer restrictions than specified by JPA. In general, sub-queries and object path expressions are allowed in most places, including:
Sub-queries in the select, group by, and order clauses;
Sub-query usage with functions;
in usage with object path expressions;
Order by usage with object path expressions.
EclipseLink's Criteria
API support is built on top of EclipseLink native Expression
API. EclipseLink provides the JpaCriteriaBuilder
interface to allow the conversion of native Expression
objects to and from JPA Expression
objects. This allows the EclipseLink native Expression
API to be mixed with the JPA Criteria
API.
The EclipseLink native Expression
API provides the following additional functionality:
Additional database functions (over 80 database functions are supported)
Usage of custom ExpressionOperators
Embedding of SQL within an Expression
query
Usage of sub-selects in the from clause
ON
clause support
Access to unmapped columns and tables
Historical querying
EclipseLink Expressions
can be combined with EclipseLink DatabaseQuerys
to provide additional functionality:
Unions, intersect and except clauses;
Hierarchical connect by clauses;
Batch fetching.