Named Queries
About
Named Queries in JPA are pre-defined static queries that are given a name and defined either via annotations or XML. These queries are typically written in JPQL and are associated with entity classes. Once defined, they can be invoked by name through the EntityManager
or Spring Data JPA repository.
Why use Named Queries?
Centralized query management
Reuse across multiple classes/methods
Better for static, frequently-used queries
Pre-compilation in some JPA implementations for performance boost
Characteristics
Static
Defined once and reused; cannot be dynamically changed.
Precompiled
May be compiled during startup (depends on JPA provider like Hibernate).
Scoped to Entity
Defined on an entity class.
Readable and Reusable
Named queries can be referenced easily throughout the application.
Better for Shared Queries
Useful when multiple services/repositories use the same query.
Syntax Structure
Annotation-based Named Query
Use @NamedQuery
or @NamedQueries
on the entity class.
@Entity
@NamedQuery(
name = "Employee.findByDepartment",
query = "SELECT e FROM Employee e WHERE e.department = :dept"
)
public class Employee {
@Id
private Long id;
private String name;
private String department;
}
XML-based Named Query (persistence.xml)
<named-query name="Employee.findByDepartment">
<query>SELECT e FROM Employee e WHERE e.department = :dept</query>
</named-query>
Accessing Named Query
Using EntityManager
:
List<Employee> employees = entityManager
.createNamedQuery("Employee.findByDepartment", Employee.class)
.setParameter("dept", "IT")
.getResultList();
Using Spring Data JPA:
@Query(name = "Employee.findByDepartment")
List<Employee> findByDepartment(@Param("dept") String department);
Where Can You Declare Named Queries?
1. On the Entity Class (Most Common & Recommended)
This is the standard and preferred way.
@Entity
@NamedQuery(
name = "Employee.findByDepartment",
query = "SELECT e FROM Employee e WHERE e.department = :dept"
)
public class Employee {
// fields...
}
The JPA provider scans the entity class and registers the query automatically at startup.
2. In persistence.xml
(Less Common)
persistence.xml
(Less Common)We can define named queries in XML instead of annotations.
<named-query name="Employee.findByDepartment">
<query>SELECT e FROM Employee e WHERE e.department = :dept</query>
</named-query>
Useful when:
We don’t want query logic in code.
We are externalizing queries for maintainability or tools.
3. In Mapped Superclass or Embeddable?
Not supported. We cannot define @NamedQuery
inside a @MappedSuperclass
or @Embeddable
.
4. Outside Entity Class?
There’s no support for declaring named queries in arbitrary classes or repositories.
However, if we're using Spring Data JPA, we can define static queries using @Query
in repository interfaces instead of NamedQuery.
@Query("SELECT e FROM Employee e WHERE e.department = :dept")
List<Employee> findByDepartment(@Param("dept") String dept);
Equivalent in functionality, but avoids the need for @NamedQuery
.
Examples
1. Find Employees by Department
@NamedQuery(
name = "Employee.findByDepartment",
query = "SELECT e FROM Employee e WHERE e.department = :dept"
)
List<Employee> result = em.createNamedQuery("Employee.findByDepartment", Employee.class)
.setParameter("dept", "Sales")
.getResultList();
2. Find Employees with Salary Above Threshold
@NamedQuery(
name = "Employee.findHighEarners",
query = "SELECT e FROM Employee e WHERE e.salary > :minSalary"
)
3. Count Employees in Department
@NamedQuery(
name = "Employee.countByDepartment",
query = "SELECT COUNT(e) FROM Employee e WHERE e.department = :dept"
)
Last updated
Was this helpful?