Close

Spring Data JPA - Using JPA Named Queries

[Last Updated: May 29, 2018]

In Spring DATA, using method names to have queries generated automatically is quite convenient, but there might be situations in which either the method name parser does not support the keyword we want to use or the method name would get unnecessarily ugly. There we can use JPA named queries which is automatically mapped to a repository method by Spring Data.

Example

JPA entity with @NamedQuery

@Entity
@NamedQuery(name= "Employee.findMaxSalariesByDept",
      query = "SELECT e.dept, MAX(e.salary) FROM Employee e GROUP BY e.dept HAVING e.dept in ?1")
public class Employee {
  private @Id
  @GeneratedValue
  Long id;
  private String name;
  private String dept;
  private int salary;
    .............
}

JPA Repository

public interface EmployeeRepository extends CrudRepository<Employee, Long> {

  public List<Object[]> findMaxSalariesByDept(List<String> deptNames);
}

Spring resolves a call to the repository methods to a named query (if it exists) by mapping the simple entity class name, followed by the repository method name separated by a dot.

Example client

@Component
public class ExampleClient {

  @Autowired
  private EmployeeRepository repo;

  public void run() {
      List<Employee> employees = createEmployees();
      repo.saveAll(employees);

      System.out.println(" -- finding all employees --");
      Iterable<Employee> all = repo.findAll();
      all.forEach(System.out::println);

      System.out.println(" -- finding max salaries in Admin and IT depts  --");
      List<Object[]> list = repo.findMaxSalariesByDept(Arrays.asList("Admin", "IT"));
      list.forEach(arr -> {
          System.out.println(Arrays.toString(arr));
      });
  }

  private List<Employee> createEmployees() {
      return Arrays.asList(
              Employee.create("Diana", "Admin", 2000),
              Employee.create("Mike", "Sale", 1000),
              Employee.create("Rose", "IT", 4000),
              Employee.create("Sara", "Admin", 3500),
              Employee.create("Randy", "Sale", 3000),
              Employee.create("Charlie", "IT", 2500)
      );
  }
}

Main class

public class ExampleMain {

  public static void main(String[] args) {
      AnnotationConfigApplicationContext context =
              new AnnotationConfigApplicationContext(AppConfig.class);
      ExampleClient exampleClient = context.getBean(ExampleClient.class);
      exampleClient.run();
      EntityManagerFactory emf = context.getBean(EntityManagerFactory.class);
      emf.close();
  }
}
 -- finding all employees --
Employee{id=1, name='Diana', dept='Admin', salary=2000}
Employee{id=2, name='Mike', dept='Sale', salary=1000}
Employee{id=3, name='Rose', dept='IT', salary=4000}
Employee{id=4, name='Sara', dept='Admin', salary=3500}
Employee{id=5, name='Randy', dept='Sale', salary=3000}
Employee{id=6, name='Charlie', dept='IT', salary=2500}
-- finding max salaries in Admin and IT depts --
[IT, 4000]
[Admin, 3500]

Query Lookup Strategies

In Java configuration, we can use the queryLookupStrategy attribute of the EnableJpaRepositories annotation which selects the strategy for how queries are created/mapped.

The following strategies are supported.

  • CREATE

    Generates the underlying store specific query by 'query method name', as we saw in the previous tutorials.

  • USE_DECLARED_QUERY

    Tries to find a declared query. A query can be declared by using @NamedQuery or @Query (next tutorial). An exception is thrown if the query cannot be found during startup time.

  • CREATE_IF_NOT_FOUND (default)

    It combines CREATE and USE_DECLARED_QUERY. It looks up a declared query first. If no declared query is found, it generates method name-based query.

Example Project

Dependencies and Technologies Used:

  • spring-data-jpa 2.0.6.RELEASE: Spring Data module for JPA repositories.
    Uses org.springframework:spring-context version 5.0.5.RELEASE
  • hibernate-core 5.2.13.Final: The core O/RM functionality as provided by Hibernate.
    Implements javax.persistence:javax.persistence-api version 2.1
  • h2 1.4.196: H2 Database Engine.
  • JDK 1.8
  • Maven 3.3.9

Spring data with JPA @NamedQuery example. Select All Download
  • spring-data-jpa-named-query
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • Employee.java
          • resources
            • META-INF

    See Also