Open In App

JPA – Criteria API

Last Updated : 09 Apr, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

In Java, JPA is defined as Java Persistence API, and the Criteria API provides a powerful tool for constructing the queries dynamically at the runtime. Unlike the JPQL (Java Persistence Query Language) which uses the strings to represent the queries programmatically.

Criteria API in JPA

The JPA Criteria API allows the developers to create queries using the fluent API approach. It comprises the set of classes and interfaces to define the query elements such as the selections, conditions, joins, and ordering criteria.

Steps to understand how to use the Criteria API

Below are the steps to know the working of Criteria API in JPA.

Step 1: Building the Criteria Query

We can begin by creating a CriteriaBuilder instance which acts as the factory for the query elements. The below code snippet demonstrates the initialization of the CriteriaBuilder.

CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();

Step 2: Creating the CriteriaQuery

We can create the CriteriaQuery Object. It can be specifying the result type of the query. This step defines what type of object the query will be retrieve.

Example:

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

Step 3: Defining the Query Elements

We can proceed to define the query elements such as the selections, conditions, joins, and ordering criteria using CriteriaQuery’s methods. For instance, to select the specific attributes.

Root<Employee> root = criteriaQuery.from(Employee.class);
criteriaQuery.select(root.get("name"));

Step 4: Executing the Query

Finally, we can execute the query using EntityManager’s createQuery method of the JPA application. The below code snippet for the demonstration of the topic.

TypedQuery<String> typedQuery = entityManager.createQuery(criteriaQuery);
List<String> names = typedQuery.getResultList();

Key Components

There are some futher subpoints that we need to know the concept of Criteria API of JPA.

Predicates and Expressions:

  • Predicates: Criteria API can provides the Predicate interface to the represent conditions in the query. these can be combined using the logical operators like AND, OR etc.
  • Expressions: It can be represents the values, paths or the functions in the query. CriteriaBuilder can provides the methods to the create expressions for various purposes.

Joins:

Criteria API can supports the different types of the joins like inner join, left join and right join. Developers can construct the join conditions dynamically based on the requirements.

CriteriaQuery Functions:

Criteria API can offers the functions to the perform the operations like aggregation, mathematical calculations, date/time manipulations etc.., directly into the query.

Implementation of Criteria API in JPA

We can develop the simple JPA application that can demonstrate the Criteria API clause of the application.

Step 1: Create the new JPA project using the Intellj Idea named jpa-criteria-api-demo. After creating the project, the file structure looks like the below image.

Project Structure


Step 2: Open the pom.xml and add the below dependencies into the project.

 <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>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>


Step 3: Open the persistence.xml and put the below code into the project and it can configure the database of the project.

XML
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence xmlns="https://jakarta.ee/xml/ns/persistence"
             xmlns:xsi="http://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 new Entity Java class named as the Employee.

Go to src > main > java > model > Employee and put the below code.

Java
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 new Java main class named as the MainApplication.

Go to src > main > java > MainApplication and put the below code.

Java
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;
import jakarta.persistence.TypedQuery;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Predicate;
import jakarta.persistence.criteria.Root;
import model.Employee;

import java.util.List;

public class MainApplication 
{

    public static void main(String[] args) {
        // Create EntityManagerFactory and EntityManager
        EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("example-unit");
        EntityManager entityManager = entityManagerFactory.createEntityManager();

        try {
            // Start a transaction
            entityManager.getTransaction().begin();

            // Insert sample employee data
            persistSampleData(entityManager);

            // Commit the transaction
            entityManager.getTransaction().commit();

            // Construct a CriteriaBuilder
            CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();

            // Create a CriteriaQuery for Employee objects
            CriteriaQuery<Employee> criteriaQuery = criteriaBuilder.createQuery(Employee.class);

            // Set the root of the query
            Root<Employee> root = criteriaQuery.from(Employee.class);

            // Specify the selection
            criteriaQuery.select(root);

            // Create a predicate for salary greater than 50000
            Predicate salaryGreaterThan = criteriaBuilder.greaterThan(root.get("salary"), 50000);

            // Set the WHERE clause
            criteriaQuery.where(salaryGreaterThan);

            // Create a TypedQuery based on the CriteriaQuery
            TypedQuery<Employee> typedQuery = entityManager.createQuery(criteriaQuery);

            // Execute the query and retrieve the result list
            List<Employee> employees = typedQuery.getResultList();
            System.out.println("Employees names of the salaries geater than 50000");

            // Print the names of employees with salary greater than 50000
            employees.forEach(employee -> System.out.println(employee.getName()));
        } finally {
            // Close EntityManager and EntityManagerFactory
            entityManager.close();
            entityManagerFactory.close();
        }
    }

    // Method to insert sample employee data
    private static void persistSampleData(EntityManager entityManager) {
        Employee employee1 = new Employee("Raju Kumar", 60000);
        Employee employee2 = new Employee("Eswar", 75000);
        Employee employee3 = new Employee("Jagan", 55000);
        Employee employee4 = new Employee("Syam", 85000);
        Employee employee5 = new Employee("Mukes", 35000);

        entityManager.persist(employee1);
        entityManager.persist(employee2);
        entityManager.persist(employee3);
        entityManager.persist(employee4);
        entityManager.persist(employee5);
    }
}

pom.xml:

XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>jpa-criteria-api-demo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>jpa-criteria-api-demo</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.target>11</maven.compiler.target>
        <maven.compiler.source>11</maven.compiler.source>
        <junit.version>5.9.2</junit.version>
    </properties>

    <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>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
        </plugins>
    </build>
</project>


Step 6: 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.

Console Output

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.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads