ObjectDB ObjectDB

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.

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).

The following query retrieves country names with their capital city names:
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.PathJPA interfaceRepresents a simple or compound attribute path from a bound type or collection, and is a "primitive" expression.See JavaDoc Reference Page... interface and by its subinterfaces (Fromjavax.persistence.criteria.FromJPA interfaceRepresents 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.See JavaDoc Reference Page..., Rootjavax.persistence.criteria.RootJPA interfaceA root type in the from clause.See JavaDoc Reference Page..., Joinjavax.persistence.criteria.JoinJPA interfaceA join to an entity, embeddable, or basic type.See JavaDoc Reference Page... and Join's descendants).

Path Expressions

The Rootjavax.persistence.criteria.RootJPA interfaceA root type in the from clause.See JavaDoc Reference Page... and Joinjavax.persistence.criteria.JoinJPA interfaceA join to an entity, embeddable, or basic type.See JavaDoc Reference Page... interfaces (which are subinterfaces of Fromjavax.persistence.criteria.FromJPA interfaceRepresents 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.See JavaDoc Reference Page...) represent FROM variables.  FROM variable expressions are considered as basic paths and also serve as a starting point for building more complex paths through navigation.

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 getget(attributeName)Path's methodCreate a path corresponding to the referenced attribute.See JavaDoc Reference Page... method:

  // FROM Variable Paths:
  Rootjavax.persistence.criteria.RootJPA interfaceA root type in the from clause.See JavaDoc Reference Page...<Country> country = query.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);
  Joinjavax.persistence.criteria.JoinJPA interfaceA join to an entity, embeddable, or basic type.See JavaDoc Reference Page...<Country, Country> neighborCountry = country.joinjoin(attributeName)From's methodCreate an inner join to the specified attribute.See JavaDoc Reference Page...("neighbors");

  // Navigation Paths:
  Pathjavax.persistence.criteria.PathJPA interfaceRepresents a simple or compound attribute path from a 
 bound type or collection, and is a "primitive" expression.See JavaDoc Reference Page...<String> countryName = country.getget(attributeName)Path's methodCreate a path corresponding to the referenced attribute.See JavaDoc Reference Page...("name");
  Pathjavax.persistence.criteria.PathJPA interfaceRepresents a simple or compound attribute path from a 
 bound type or collection, and is a "primitive" expression.See JavaDoc Reference Page...<City> capital = country.getget(attributeName)Path's methodCreate a path corresponding to the referenced attribute.See JavaDoc Reference Page...("capital");
  Pathjavax.persistence.criteria.PathJPA interfaceRepresents a simple or compound attribute path from a 
 bound type or collection, and is a "primitive" expression.See JavaDoc Reference Page...<String> captialName = capital.getget(map)Path's methodCreate a path corresponding to the referenced 
  map-valued attribute.See JavaDoc Reference Page...("name");

The path expressions in the above code can be divided into two main groups:

Type Expressions

Entity type expressions can be constructed by the Pathjavax.persistence.criteria.PathJPA interfaceRepresents a simple or compound attribute path from a bound type or collection, and is a "primitive" expression.See JavaDoc Reference Page...'s typetype()Path's methodCreate an expression corresponding to the type of the path.See JavaDoc Reference Page... method. For example, the following criteria expression checks if the type of a specified entity e is not Country.

  Predicatejavax.persistence.criteria.PredicateJPA interfaceThe type of a simple or compound predicate: a conjunction or
 disjunction of restrictions.See JavaDoc Reference Page... p = cb.notEqualnotEqual(x, y)CriteriaBuilder's methodCreate a predicate for testing the arguments for inequality.See JavaDoc Reference Page...(e.typetype()Path's methodCreate an expression corresponding to the type of the path.See JavaDoc Reference Page...(), cb.literalliteral(value)CriteriaBuilder's methodCreate an expression for a literal.See JavaDoc Reference Page...(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).