In Java, JPA (Java Persistence API) provides a standard for mapping Java objects to database tables. The Criteria API is a feature of JPA that allows developers to build dynamic, type-safe queries programmatically at runtime, unlike JPQL, which relies on string-based queries.
The Criteria API is particularly useful when the query structure is not fixed and must be created dynamically based on runtime conditions.
Key Concepts of Criteria API
- CriteriaBuilder: Factory for creating query elements such as Predicate, Expression, and CriteriaQuery, and obtained from the EntityManager.
- CriteriaQuery: Represents the query definition, including selections, conditions, ordering, and joins.
- Root: Defines the entity to query. Equivalent to the FROM clause in SQL.
- Predicate: Represents a condition in the query, such as WHERE salary > 50000.
- Expressions: Represents columns, functions, or calculations.
- TypedQuery: Executes the CriteriaQuery to return the results.
Implementation of Criteria API in JPA
We can develop a simple JPA application that can demonstrate the Criteria API clause of the application.
Step 1: Create a New Maven Project
- Use IntelliJ IDEA or any IDE.
- Project name: jpa-criteria-api-demo
- Java version: 11+
- Packaging: Jar
Project Structure:

Step 2: Add Dependencies in pom.xml
Open the pom.xml and add the below dependencies into the project.
<dependencies>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.0.2.Final</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.9.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.9.2</version>
<scope>test</scope>
</dependency>
</dependencies>
Step 3: Configure persistence.xml
Open the persistence.xml and put the below code into the project and it can configure the database of the project.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence xmlns="https://jakarta.ee/xml/ns/persistence/"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence/ https://jakarta.ee/xml/ns/persistence//persistence_3_0.xsd"
version="3.0">
<persistence-unit name="example-unit">
<class>model.Employee</class>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/example"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value=""/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
</persistence>
Step 4: Create the Employee Entity
- Create the new Entity Java class named as the Employee.
- Go to src > main > java > model > Employee and put the below code.
package model;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private double salary;
// Default constructor required by JPA
protected Employee() {}
public Employee(String name, double salary)
{
this.name = name;
this.salary = salary;
}
// Getters and setters
public Long getId()
{
return id;
}
public void setId(Long id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public double getSalary()
{
return salary;
}
public void setSalary(double salary)
{
this.salary = salary;
}
}
Step 5: Create the Main Application
- Create the new Java main class named as the MainApplication.
- Go to src > main > java > MainApplication and put the below code.
import jakarta.persistence.*;
import jakarta.persistence.criteria.*;
import model.Employee;
import java.util.List;
public class MainApplication {
public static void main(String[] args) {
// Create EntityManager
EntityManagerFactory emf = Persistence.createEntityManagerFactory("example-unit");
EntityManager em = emf.createEntityManager();
try {
// Begin transaction
em.getTransaction().begin();
// Insert sample data
persistSampleData(em);
// Commit transaction
em.getTransaction().commit();
// Create CriteriaBuilder
CriteriaBuilder cb = em.getCriteriaBuilder();
// Create CriteriaQuery for Employee
CriteriaQuery<Employee> cq = cb.createQuery(Employee.class);
// Define query root
Root<Employee> root = cq.from(Employee.class);
// Specify selection and condition
cq.select(root)
.where(cb.greaterThan(root.get("salary"), 50000));
// Execute query
TypedQuery<Employee> query = em.createQuery(cq);
List<Employee> result = query.getResultList();
System.out.println("Employees with salary > 50000:");
result.forEach(e -> System.out.println(e.getName()));
} finally {
em.close();
emf.close();
}
}
private static void persistSampleData(EntityManager em) {
em.persist(new Employee("Raju Kumar", 60000));
em.persist(new Employee("Eswar", 75000));
em.persist(new Employee("Jagan", 55000));
em.persist(new Employee("Syam", 85000));
em.persist(new Employee("Mukes", 35000));
}
}
Step 6: Run the Application
Once the project is completed, run the application. It will then show the Employee name whose salary is greater than 50000 as output. Refer the below output image for better understanding of the concept.

In the above project, we have demonstrated the usage of the JPA Criteria API to the query and retrieve the data from the database of the JPA applications.