Close

JPA Criteria API - Using Literals

[Updated: Aug 14, 2018, Created: Aug 14, 2018]

This tutorial will show how to use literals in JPA Criteria API.

The result of a query can be restricted by specifying one or more predicate conditions. CriteriaBuilder has various methods to create an instance of Predicate. The predicate object is passed to one of the CriteriaBuilder methods which apply the restriction. For example:

 CriteriaQuery<T> where(Predicate... restrictions);

A simple predicate is created by invoking one of the conditional method of the CriteriaBuilder, for example

Predicate equal(Expression<?> x, Object y);

The second parameter of the above method represents the right-hand side operator of the predicate which can be a literal. For example:

  CriteriaQuery<Employee> query = criteriaBuilder.createQuery(Employee.class);
  Root<Employee> employee = query.from(Employee.class);
  query.select(employee)
       .where(criteriaBuilder.equal(employee.get(Employee_.name), "Linda"));

There's another overload equal() method which accepts right-hand side operator as Expression:

Predicate equal(Expression<?> x, Expression<?> y);

CriteriaBuilder<T> provides following method to create an expression for a literal:

Expression<T> literal(T value);

Above example snippet can be rewritten as:

  CriteriaQuery<Employee> query = criteriaBuilder.createQuery(Employee.class);
  Root<Employee> employee = query.from(Employee.class);
  query.select(employee)
       .where(criteriaBuilder.equal(employee.get(Employee_.name), criteriaBuilder.literal("Linda")));

The method CriteriaBuilder.literal() can be useful to create dynamic queries.

CriteriaBuilder provides another method to create null literal expression:

Expression<T> nullLiteral(Class<T> resultClass);

Example

Entity

@Entity
public class Employee {
  @Id
  @GeneratedValue
  private long id;
  private String name;
  private double salary;
  private LocalDate joinDate;
  private Dept dept;
    .............
}
public enum Dept {
IT, Admin, Sales
}

Using literals

public class ExampleMain {
  private static EntityManagerFactory entityManagerFactory =
          Persistence.createEntityManagerFactory("example-unit");

  public static void main(String[] args) {
      try {
          persistEmployees();
          findEmployeeByName();
          findEmployeesByDept();
          findEmployeeBySalary();
          findEmployeeByJoinDate();
          findEmployeeWithNullJoinDate();

      } finally {
          entityManagerFactory.close();
      }
  }

  public static void persistEmployees() {
      Employee employee1 = Employee.create("Diana", 2000, Dept.IT,
              LocalDate.of(2010, 4, 1));
      Employee employee2 = Employee.create("Rose", 4500, Dept.Admin,
              LocalDate.of(2009, 7, 1));
      Employee employee3 = Employee.create("Denise", 2000, Dept.Admin,
              LocalDate.of(2002, 2, 1));
      Employee employee4 = Employee.create("Mike", 4000, Dept.IT,
              LocalDate.of(2007, 10, 1));
      Employee employee5 = Employee.create("Linda", 4500, Dept.Sales,
              null);
      EntityManager em = entityManagerFactory.createEntityManager();
      em.getTransaction().begin();
      em.persist(employee1);
      em.persist(employee2);
      em.persist(employee3);
      em.persist(employee4);
      em.persist(employee5);
      em.getTransaction().commit();
      System.out.println("-- employee persisted --");
      CriteriaQuery<Employee> query = em.getCriteriaBuilder()
                                        .createQuery(Employee.class);
      query.select(query.from(Employee.class));
      em.createQuery(query).getResultList().forEach(System.out::println);
      em.close();
  }

  private static void findEmployeeByName() {
      System.out.println("-- Finding employee by name --");
      EntityManager em = entityManagerFactory.createEntityManager();
      CriteriaBuilder cBuilder = em.getCriteriaBuilder();
      CriteriaQuery<Employee> query = cBuilder.createQuery(Employee.class);
      Root<Employee> employee = query.from(Employee.class);
      Expression<String> linda = cBuilder.literal("Linda");
      query.select(employee)
           .where(cBuilder.equal(employee.get(Employee_.name), linda));
      TypedQuery<Employee> tq = em.createQuery(query);
      List<Employee> resultList = tq.getResultList();
      resultList.forEach(System.out::println);
  }

  private static void findEmployeesByDept() {
      System.out.println("-- Finding employee by dept IT --");
      EntityManager em = entityManagerFactory.createEntityManager();
      CriteriaBuilder cBuilder = em.getCriteriaBuilder();
      CriteriaQuery<Employee> query = cBuilder.createQuery(Employee.class);
      Root<Employee> employee = query.from(Employee.class);
      query.select(employee)
           .where(cBuilder.equal(employee.get(Employee_.DEPT), Dept.IT));
      TypedQuery<Employee> tq = em.createQuery(query);
      List<Employee> resultList = tq.getResultList();
      resultList.forEach(System.out::println);
  }

  private static void findEmployeeBySalary() {
      System.out.println("-- finding employee with salary greater than 4000 inclusively --");
      EntityManager em = entityManagerFactory.createEntityManager();
      CriteriaBuilder cBuilder = em.getCriteriaBuilder();
      CriteriaQuery<Employee> query = cBuilder.createQuery(Employee.class);
      Root<Employee> employee = query.from(Employee.class);
      query.select(employee)
           .where(cBuilder.ge(employee.get(Employee_.salary), cBuilder.literal(4000)));
      TypedQuery<Employee> tq = em.createQuery(query);
      List<Employee> resultList = tq.getResultList();
      resultList.forEach(System.out::println);
  }

  private static void findEmployeeByJoinDate() {
      System.out.println("-- finding employee with join date between 2005 to 2010 inclusively --");
      EntityManager em = entityManagerFactory.createEntityManager();
      CriteriaBuilder cBuilder = em.getCriteriaBuilder();
      CriteriaQuery<Employee> query = cBuilder
              .createQuery(Employee.class);
      Root<Employee> employee = query.from(Employee.class);
      query.select(employee)
           .where(cBuilder.between(employee.get(Employee_.JOIN_DATE),
                   LocalDate.of(2005, 1, 1),
                   LocalDate.of(2011, 1, 1)
           ));
      TypedQuery<Employee> tq = em.createQuery(query);
      List<Employee> resultList = tq.getResultList();
      resultList.forEach(System.out::println);
  }

  private static void findEmployeeWithNullJoinDate() {
      System.out.println("-- finding employee with null join date  --");
      EntityManager em = entityManagerFactory.createEntityManager();
      CriteriaBuilder cBuilder = em.getCriteriaBuilder();
      CriteriaQuery<Employee> query = cBuilder.createQuery(Employee.class);
      Root<Employee> employee = query.from(Employee.class);
      query.select(employee)
           .where(cBuilder.equal(employee.get(Employee_.JOIN_DATE),
              cBuilder.nullLiteral(LocalDate.class)));
      TypedQuery<Employee> tq = em.createQuery(query);
      List<Employee> resultList = tq.getResultList();
      resultList.forEach(System.out::println);
  }
}
-- employee persisted --
Employee{id=1, name='Diana', salary=2000.0, joinDate=2010-04-01, dept=IT}
Employee{id=2, name='Rose', salary=4500.0, joinDate=2009-07-01, dept=Admin}
Employee{id=3, name='Denise', salary=2000.0, joinDate=2002-02-01, dept=Admin}
Employee{id=4, name='Mike', salary=4000.0, joinDate=2007-10-01, dept=IT}
Employee{id=5, name='Linda', salary=4500.0, joinDate=null, dept=Sales}
-- Finding employee by name --
Employee{id=5, name='Linda', salary=4500.0, joinDate=null, dept=Sales}
-- Finding employee by dept IT --
Employee{id=1, name='Diana', salary=2000.0, joinDate=2010-04-01, dept=IT}
Employee{id=4, name='Mike', salary=4000.0, joinDate=2007-10-01, dept=IT}
-- finding employee with salary greater than 4000 inclusively --
Employee{id=2, name='Rose', salary=4500.0, joinDate=2009-07-01, dept=Admin}
Employee{id=4, name='Mike', salary=4000.0, joinDate=2007-10-01, dept=IT}
Employee{id=5, name='Linda', salary=4500.0, joinDate=null, dept=Sales}
-- finding employee with join date between 2005 to 2010 inclusively --
Employee{id=1, name='Diana', salary=2000.0, joinDate=2010-04-01, dept=IT}
Employee{id=2, name='Rose', salary=4500.0, joinDate=2009-07-01, dept=Admin}
Employee{id=4, name='Mike', salary=4000.0, joinDate=2007-10-01, dept=IT}
-- finding employee with null join date --
Employee{id=5, name='Linda', salary=4500.0, joinDate=null, dept=Sales}

Example Project

Dependencies and Technologies Used:

  • h2 1.4.197: H2 Database Engine.
  • hibernate-core 5.3.4.Final: Hibernate's core ORM functionality.
    Implements javax.persistence:javax.persistence-api version 2.2
  • hibernate-jpamodelgen 5.3.2.Final: Annotation Processor to generate JPA 2 static metamodel classes.
  • JDK 1.8
  • Maven 3.5.4

Using Literals in Criteria Select All Download
  • jpa-criteria-api-using-literals
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • ExampleMain.java
          • resources
            • META-INF

    See Also