Literals in JPQL and Criteria Queries

Literals in JPQL, as in Java, represent constant values. JPQL supports various types of literals including NULL, boolean literals (TRUE and FALSE), numeric literals (e.g. 100), string literals (e.g. 'abc'), enum literals (e.g. mypackage.MyEnum.MY_VALUE) and entity type literals (e.g. Country).

JPQL literals should be used sparingly as queries that use parameters instead of literals are more generic and efficient because they can be compiled once and then run many times with different parameter values. Literals should only be embedded in JPQL queries when a single constant value is always used and never replaced.

The NULL literal

The NULL literal represents a null value, similarly to null in Java and SQL. Since JPQL is case insensitive, NULL, null and Null are equivalent. Notice that comparison with NULL in JPQL follows the SQL rules for NULL comparison rather than the Java rules, as explained in the Comparison Operators page.

Boolean Literals

Similarly to Java and SQL, JPQL supports two boolean literals - TRUE and FALSE. Since JPQL is case insensitive, TRUE is equivalent to true and True, and FALSE is equivalent to false and False.

Numeric Literals

JPQL supports the Java syntax as well as the SQL syntax for numeric literals. Numeric suffixes (e.g. 1.5F) are also supported. Following are examples of valid numeric literals in JPQL:

  • int: 100, -127, 0, 07777
  • long: 100L, -127L, 0L, 07777L
  • float: 3.14F, 0f, 1e2f, -2.f, 5.04e+17f
  • double: 3.14, 0d, 1e2D, -2., 5.04e+17

ObjectDB also supports hexadecimal numeric literals (e.g. 0xFF, 0xFFL) and octal numeric literals (e.g. 077, 077L), a feature that is not currently supported by all JPA implementations.

String Literals

JPQL follows the syntax of SQL for string literals in which strings are always enclosed in single quotes (e.g. 'Adam', '') and a single quote character in a string is represented by two single quotes (e.g. 'Adam''s').

ObjectDB also supports the syntax of Java and JDO for string literals in which strings are enclosed with double quotes (e.g. "Adam", "") and Java escape characters can be used (e.g. "Adam\'s", "abcd\n1234") but this is not supported by all the JPA implementations.

Unlike most other JPQL components, String literals (which represent data) are case sensitive, so 'abc' and 'ABC' are not equivalent.

Date and Time Literals

JPQL follows the syntax of SQL and JDBC for date literals:

  • Date - {d 'yyyy-mm-dd'} - for example: {d '2019-12-31'}
  • Time - {t 'hh:mm:ss'} - for example: {t '23:59:59'}
  • Timestamp - {ts 'yyyy-mm-dd hh:mm:ss'} - for example: {ts '2020-01-03 13:59:59'}

Enum Literals

JPA 2 adds support for enum literals. Enum literals in JPQL queries use the ordinary Java syntax for enum values, but the fully qualified name of the enum type should always be specified.

For example, assuming we have the following enum definition:

package example.ui;

enum Color { RED, GREEN, BLUE }

Then example.ui.Color.RED is a valid literal in JPQL, but Color.RED is not.

Entity Type Literals

Entity type literals represent entity types in JPQL, similar to the way that java.lang.Class instances in Java represent Java types. Entity type literals have been added in JPA 2 to enable selective retrieval by type.

In JPQL an entity type literal is written simply as the name of the entity class (e.g. Country).
That is equivalent to Country.class in Java code. Notice that the name of the entity class is not enclosed in quotes (because type literals are not string literals).

By default, the name of an entity class is its unqualified name (i.e. excluding package name) but it can be modified by specifying another name explicitly in the @Entityjavax.persistence.Entity - JPA AnnotationSpecifies that the class is an entity.'s namejavax.persistence.Entity.name - JPA Annotation Attribute(Optional) The entity name. annotation element.

Criteria Query Literals

The CriteriaBuilderjavax.persistence.criteria.CriteriaBuilder - JPA InterfaceUsed to construct criteria queries, compound selections, expressions, predicates, orderings. interface provides two factory methods for building literal expressions.

Ordinary Literals

The main method, literalCriteriaBuilder.literal(value) - JPA MethodCreate an expression for a literal., takes a Java object and returns a literal expression. For example:

  // Boolean literals:
  Expressionjavax.persistence.criteria.Expression - JPA InterfaceType for query expressions.<Boolean> t = cb.literalCriteriaBuilder.literal(value) - JPA MethodCreate an expression for a literal.(true);
  Expressionjavax.persistence.criteria.Expression - JPA InterfaceType for query expressions.<Boolean> f = cb.literalCriteriaBuilder.literal(value) - JPA MethodCreate an expression for a literal.(Boolean.FALSE);

  // Numeric literals:
  Expressionjavax.persistence.criteria.Expression - JPA InterfaceType for query expressions.<Integer> i1 = cb.literalCriteriaBuilder.literal(value) - JPA MethodCreate an expression for a literal.(1);
  Expressionjavax.persistence.criteria.Expression - JPA InterfaceType for query expressions.<Integer> i2 = cb.literalCriteriaBuilder.literal(value) - JPA MethodCreate an expression for a literal.(Integer.ValueOf(2));
  Expressionjavax.persistence.criteria.Expression - JPA InterfaceType for query expressions.<Double> d = cb.literalCriteriaBuilder.literal(value) - JPA MethodCreate an expression for a literal.(3.4);

  // String literals:
  Expressionjavax.persistence.criteria.Expression - JPA InterfaceType for query expressions.<String> empty = cb.literalCriteriaBuilder.literal(value) - JPA MethodCreate an expression for a literal.("");
  Expressionjavax.persistence.criteria.Expression - JPA InterfaceType for query expressions.<String> jpa = cb.literalCriteriaBuilder.literal(value) - JPA MethodCreate an expression for a literal.("JPA");

  // Date and Time literals:
  Expressionjavax.persistence.criteria.Expression - JPA InterfaceType for query expressions.<java.sql.Date> today = cb.literalCriteriaBuilder.literal(value) - JPA MethodCreate an expression for a literal.(new java.sql.Date());
  Expressionjavax.persistence.criteria.Expression - JPA InterfaceType for query expressions.<java.sql.Time> time = cb.literalCriteriaBuilder.literal(value) - JPA MethodCreate an expression for a literal.(new java.sql.Time());
  Expressionjavax.persistence.criteria.Expression - JPA InterfaceType for query expressions.<java.sql.Timestamp> now = cb.literalCriteriaBuilder.literal(value) - JPA MethodCreate an expression for a literal.(new java.sql.Timestamp());

  // Enum literal:
  Expressionjavax.persistence.criteria.Expression - JPA InterfaceType for query expressions.<Color> red = cb.literalCriteriaBuilder.literal(value) - JPA MethodCreate an expression for a literal.(Color.RED);

  // Entity Type literal:
  Expressionjavax.persistence.criteria.Expression - JPA InterfaceType for query expressions.<Class> type = cb.literalCriteriaBuilder.literal(value) - JPA MethodCreate an expression for a literal.(MyEntity.class);

Null Literals

Null literal expressions can be built by the ordinary literalCriteriaBuilder.literal(value) - JPA MethodCreate an expression for a literal. method:

  Expressionjavax.persistence.criteria.Expression - JPA InterfaceType for query expressions. n = cb.literal(null);

or by a special CriteriaBuilderjavax.persistence.criteria.CriteriaBuilder - JPA InterfaceUsed to construct criteria queries, compound selections, expressions, predicates, orderings.'s method, nullLiteralCriteriaBuilder.nullLiteral(resultClass) - JPA MethodCreate an expression for a null literal with the given type., that returns a typed expression:

  Expressionjavax.persistence.criteria.Expression - JPA InterfaceType for query expressions.<String> strNull = cb.nullLiteralCriteriaBuilder.nullLiteral(resultClass) - JPA MethodCreate an expression for a null literal with the given type.(String.class);
  Expressionjavax.persistence.criteria.Expression - JPA InterfaceType for query expressions.<Integer> intNull = cb.nullLiteralCriteriaBuilder.nullLiteral(resultClass) - JPA MethodCreate an expression for a null literal with the given type.(Integer.class);