Close

JPA - Getting started with Criteria API, using Select query

[Updated: Sep 10, 2018, Created: Jul 6, 2018]

The javax.persistence.criteria API is designed to allow criteria queries to be constructed in a strongly-typed manner. To use the API, we need to be familiar with the followings:

CriteriaBuilder

This interface is the entry point to the Criteria API. It is used to construct query objects and their expressions. We can obtain the instance of this interface via EntityManager.getCriteriaBuilder() or EntityManagerFactory.getCriteriaBuilder().

EntityManager entityManager = ......
   CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();

CriteriaQuery

A CriteriaQuery object represents a query. It is created by means of one of the createQuery methods of the CriteriaBuilder interface.

CriteriaQuery<Employee> criteriaQuery = criteriaBuilder.createQuery(Employee.class);

The CriteriaQuery interface has various methods to create query clauses. For example CriteriaQuery#select() defines a 'select' clause. CriteriaQuery#where() defines the 'where' clause.

Root<T>

This represents root type of the target 'entity'. Query root references the target entity (T). The root object is obtain via CriteriaQuery#from(Class<T> entityClass) method.

Root<Employee> employeeRoot = criteriaQuery.from(Employee.class);

Constructing query

As mentioned above, different methods (select(), where() etc) of CriteriaQuery are used to create query clauses, we start building query by 'selecting' the item that is to be returned in the query result:

criteriaQuery.select(employeeRoot);

We further apply the clauses to the CriteriaQuery object by using Root instance to navigate the target entity attributes and by using CriteriaBuilder instance to build query predicates:

criteriaQuery.where(criteriaBuilder.equal(employeeRoot.get("dept"), "Admin"));

In above snippet we are using CriteriaBuilder#equal(Expression<?> x, Object y); which returns an instance of javax.persistence.criteria.Predicate.

Executing query

Here EntityManager#createQuery() method is used to get the instance of TypedQuery<T> which is then used to execute the query:

TypedQuery<Employee> typedQuery = entityManager.createQuery(criteriaQuery);
   List<Employee> list =  typedQuery.getResultList()

Example

Entity

@Entity
public class Employee {
  @Id
  @GeneratedValue
  private long id;
  private String name;
  private double salary;
  private String dept;
    .............
}

Using Criteria API

Following example executes queries involving 'select' and 'where' causes.

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

  public static void main(String[] args) {
      try {
          persistEmployees();
          findAllEmployees();
          findAdmins();
      } finally {
          entityManagerFactory.close();
      }
  }

  public static void persistEmployees() {
      Employee employee1 = Employee.create("Diana", 2000, "IT");
      Employee employee2 = Employee.create("Rose", 3500, "Admin");
      Employee employee3 = Employee.create("Denise", 2500, "Admin");
      Employee employee4 = Employee.create("Mike", 4000, "IT");
      Employee employee5 = Employee.create("Linda", 4500, "Sales");
      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();
      em.close();
  }

  private static void findAllEmployees() {
      System.out.println("-- All employees --");
      EntityManager em = entityManagerFactory.createEntityManager();
      CriteriaBuilder cb = em.getCriteriaBuilder();
      CriteriaQuery<Employee> query = cb.createQuery(Employee.class);//create query object
      Root<Employee> employeeRoot = query.from(Employee.class);//get object representing 'from' part
      query.select(employeeRoot);//linking 'select' and 'from' parts, equivalent to 'select t from Employee t;'
      TypedQuery<Employee> typedQuery = em.createQuery(query);
      typedQuery.getResultList()
                .forEach(System.out::println);
      em.close();
  }

  private static void findAdmins() {
      System.out.println("-- All employees with 'Admin' dept --");
      EntityManager em = entityManagerFactory.createEntityManager();
      CriteriaBuilder cb = em.getCriteriaBuilder();
      CriteriaQuery<Employee> query = cb.createQuery(Employee.class);
      Root<Employee> employee = query.from(Employee.class);
      query.select(employee)
           .where(cb.equal(employee.get("dept"), "Admin"));
      TypedQuery<Employee> typedQuery = em.createQuery(query);
      typedQuery.getResultList()
                .forEach(System.out::println);
      em.close();
  }
}
-- All employees --
Employee{id=1, name='Diana', salary=2000.0, dept='IT'}
Employee{id=2, name='Rose', salary=3500.0, dept='Admin'}
Employee{id=3, name='Denise', salary=2500.0, dept='Admin'}
Employee{id=4, name='Mike', salary=4000.0, dept='IT'}
Employee{id=5, name='Linda', salary=4500.0, dept='Sales'}
-- All employees with 'Admin' dept --
Employee{id=2, name='Rose', salary=3500.0, dept='Admin'}
Employee{id=3, name='Denise', salary=2500.0, dept='Admin'}

Example Project

Dependencies and Technologies Used:

  • h2 1.4.197: H2 Database Engine.
  • hibernate-core 5.3.1.Final: Hibernate's core ORM functionality.
    Implements javax.persistence:javax.persistence-api version 2.2
  • JDK 1.8
  • Maven 3.5.4

Getting started with Criteria API Select All Download
  • jpa-getting-started-with-criteria-api
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • ExampleMain.java
          • resources
            • META-INF

    See Also