Paths and Types in JPQL and Criteria API
Instances of user defined persistable classes (entity classes, mapped super classes and embeddable classes) are represented in JPQL by the following types of expressions:
- Variables - FROM identification variables and SELECT result variables.
- Parameters - when instances of these classes are assigned as arguments.
- Path expressions that navigate from one object to another.
Instances of user defined persistable classes can participate in direct comparison using the =
and <>
operators. But more often they are used in JPQL path expressions that navigate to values of simple types (number, boolean, string, date).
Simple type values are more useful in queries. They have special operators and functions (e.g. for strings and for numbers), they can be compared by all six comparison operators, and they can be used in ordering.
This page covers the following topics:
Navigation through Path Expressions
A path expression always starts with an instance of a user defined class (represented by a variable, parameter or prefix path expression) and uses the dot (.
) operator to navigate through persistent fields to other objects and values.
For example - c.capital
, where c represents a Country entity object uses the capital
persistent field in the Country
class to navigate to the associated Capital
entity object.
Path expression whose type is a persistable user class can be extended further by reusing the dot (.) operator. For example, c.capital.name
is a nested path expression that continues from the Capital entity object to its name field. A path expression can be extended further only if its type is also a user defined persistable class. The dot (.) operator cannot be applied to collections, maps and values of simple types (number, boolean, string, date).
For a path expression to be valid the user defined persistable class must contain a persistent field (or property) with a matching name. The path expression, however, is valid even if the persistent field is declared as private (which is usually the case).
Navigation through a NULL value
SELECT c.name, c.capital.name FROM Country c
The c
identification variable is used to iterate over all the Country objects in the database.
For a country with no capital city, such as Nauru, c.capital
is evaluated to NULL
and c.capital.name is an attempt to navigate from a NULL
value. In Java, a NullPointerException
is thrown on any attempt to access a field or a method via a null reference. In JPQL, the current FROM variable (or FROM tuple when there are multiple variables) is simply skipped. It might be easier to understand exactly how this works by considering the equivalent JOIN query.
Entity Type Expressions
The TYPE operator (which is new in JPA 2) returns the type of a specified argument, similarly to java.lang.Object
's getClass
method in Java.
The following query returns the number of all the entity objects in the database, excluding Country entity objects:
SELECT COUNT(e) FROM Object e WHERE TYPE(e) <> Country
Binding an identification variable (e
) to the Object class is an extension of ObjectDB that can be used to iterate over all the entity objects in the database. The Country
literal represents the Country entity class. The TYPE operator returns the actual type of the iterated e
. Only objects whose type is not Country are passed to the SELECT. The SELECT clause counts all these objects (this is an aggregate query with no GROUP BY - all the objects are considered as one group, and COUNT calculates its size).
Criteria Query Paths and Types
Paths and navigations are represented in the JPA Criteria API by the Pathjavax.persistence.criteria.Path
interface and by its subinterfaces (Fromjavax.persistence.criteria.From
, Rootjavax.persistence.criteria.Root
, Joinjavax.persistence.criteria.Join
and Join
's descendants).
Path Expressions
The Root
javax.persistence.criteria.RootJoin
javax.persistence.criteria.JoinFrom
javax.persistence.criteria.From
Giving a Path
instance, a child Path
expression (which represents navigation from the parent path through a persistent field or property), can be constructed by the getPath
method:
// FROM Variable Paths: Rootjavax.persistence.criteria.Root- JPA Interface A root type in the from clause.<Country> country = query.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); Joinjavax.persistence.criteria.Join- JPA Interface A join to an entity, embeddable, or basic type.<Country, Country> neighborCountry = country.joinFrom.join(attributeName) - JPA Method Create an inner join to the specified attribute.("neighbors"); // Navigation Paths: Pathjavax.persistence.criteria.Path- JPA Interface Represents a simple or compound attribute path from a bound type or collection, and is a "primitive" expression.<String> countryName = country.getPath.get(attributeName) - JPA Method Create a path corresponding to the referenced attribute.("name"); Pathjavax.persistence.criteria.Path- JPA Interface Represents a simple or compound attribute path from a bound type or collection, and is a "primitive" expression.<City> capital = country.getPath.get(attributeName) - JPA Method Create a path corresponding to the referenced attribute.("capital"); Pathjavax.persistence.criteria.Path- JPA Interface Represents a simple or compound attribute path from a bound type or collection, and is a "primitive" expression.<String> captialName = capital.getPath.get(map) - JPA Method Create a path corresponding to the referenced map-valued attribute.("name");
The path expressions in the above code can be divided into two main groups:
- FROM variable expressions, represented by subinterfaces of
From
javax.persistence.criteria.From- JPA Interface Represents a bound type, usually an entity that appears in the from clause, but may also be an embeddable belonging to an entity in the from clause. (Root
javax.persistence.criteria.Root- JPA Interface A root type in the from clause.,Join
javax.persistence.criteria.Join- JPA Interface A join to an entity, embeddable, or basic type.) -
The creation of a FROM expression automatically modifies the query by adding a variable to the FROM clause (representing iteration during query execution). The constructed variable expression can also be used explicitly in other query clauses. - Navigation expressions, represented by the
Path
javax.persistence.criteria.Path- JPA Interface Represents a simple or compound attribute path from a bound type or collection, and is a "primitive" expression. interface -
The creation of a navigation path expression doesn't affect the built query directly. The constructed expression must be integrated into query clauses explicitly to have an effect.
Type Expressions
Entity type expressions can be constructed by the Pathjavax.persistence.criteria.Path
's type
Pathe
is not Country
.
Predicatejavax.persistence.criteria.Predicate - JPA InterfaceThe type of a simple or compound predicate: a conjunction or disjunction of restrictions. p = cb.notEqualCriteriaBuilder.notEqual(x,y) - JPA MethodCreate a predicate for testing the arguments for inequality.(e.typePath.type() - JPA Method Create an expression corresponding to the type of the path.(), cb.literalCriteriaBuilder.literal(value) - JPA MethodCreate an expression for a literal.(Country.class));
In the above example, the comparison is between the type of the e
object (which may represent any path including a root or a join) and the entity type Country (
a criteria literal).