Named Query in JPA with example

Named Query in JPA with example

A Named Query in Java Persistence API (JPA) is a statically defined query expressed in the query language, Java Persistence Query Language (JPQL) or SQL. Named queries are defined using the @NamedQuery annotation or XML descriptor and are usually specified at the entity class level. These queries are defined once and referenced by their names in the application code.

Named queries are typically used for more complex queries that will be reused multiple times throughout an application. Defining them statically can improve code readability and maintainability, and also allows for compile-time validation of the query syntax.

Named Query in JPA with example

How is it used?

Named queries are defined using the @NamedQuery annotation at the top of an entity class. The @NamedQuery annotation takes two parameters:

  • name: A unique identifier for the query.
  • query: The JPQL or SQL query string.

Once defined, named queries can be executed using the EntityManager.createNamedQuery method, which returns a TypedQuery object that can be used to set parameters and execute the query.

Benefits of Using Named Queries

  • 1.  Maintainability : Centralizing query definitions makes them easier to manage and update.
  • 2.  Reusability : Named queries can be reused across different parts of the application.
  • 3.  Readability : Queries defined in annotations or XML descriptors make the code cleaner and more readable.
  • 4.  Performance : Named queries can be precompiled by the JPA provider, potentially improving performance.
  • 5.  Compile-time Checking : Since named queries are defined statically, the JPA provider can validate them at deployment time, reducing runtime errors.

Example in Java

Let’s create an example of a named query in a JPA entity class.

1. Define the Named Query in the Entity Class
java
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NamedQuery;

@Entity
@NamedQuery(
    name = "User.findByName",
    query = "SELECT u FROM User u WHERE u.name = :name"
)
public class User {
    @Id
    private Long id;
    private String name;
    
    // Getters and Setters
}

In this example, a named query User.findByName is defined to select users by their name.

2. Using the Named Query in Application Code
java
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.TypedQuery;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory("my-persistence-unit");
        EntityManager em = emf.createEntityManager();
        
        try {
            em.getTransaction().begin();
            
            // Use the named query
            TypedQuery<User> query = em.createNamedQuery("User.findByName", User.class);
            query.setParameter("name", "John Doe");
            List<User> users = query.getResultList();
            
            for (User user : users) {
                System.out.println("User ID: " + user.getId() + ", User Name: " + user.getName());
            }
            
            em.getTransaction().commit();
        } finally {
            em.close();
            emf.close();
        }
    }
}

In this application code, the named query User.findByName is executed to find users with the name “John Doe”. The EntityManager is used to create a TypedQuery object, set the query parameter, and retrieve the results.