Close

Spring Data JPA - Interface-based Projections

[Last Updated: Aug 28, 2018]

Projection is selecting and collecting a subset of attributes in a query.

In Spring Data JPA, the easiest way to collect projection is to declare an interface that exposes getter methods for the properties to be selected.

Consider Employee entity which has attributes id, name, dept and salary. Let's say we want to select only employee name and salary, then we can define the following interface:

public interface EmployeeSalary{
  getName();
  getSalary();
}

And then we can define following in our repository to select EmployeeSalary:

interface EmployeeRepository extends Repository<Employee, Long> {
  Collection<EmployeeSalary> findBy(String dept);
}

Complete Example

Entity

@Entity
public class Employee{
  private @Id
  @GeneratedValue
  Long id;
  private String name;
  private String dept;
  private int salary;
    .............
}

Projection interface

public interface EmployeeSalary {
  String getName();
  int getSalary();
}

Repository

public interface EmployeeRepository extends CrudRepository<Employee, Long> {
  List<EmployeeSalary> findBy();
  List<EmployeeSalary> findByDept(String dept);
}

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 all EmployeeSalary --");
      List<EmployeeSalary> list = repo.findBy();
      for (EmployeeSalary es : list) {
          System.out.printf("Name: %s, Salary: %s%n", es.getName(), es.getSalary());
      }

      System.out.println(" -- finding the EmployeeSalary in IT dept --");
      list = repo.findByDept("IT");
      for (EmployeeSalary es : list) {
          System.out.printf("Name: %s, Salary: %s%n", es.getName(), es.getSalary());
      }
  }

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

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=3000}
Employee{id=2, name='Mike', dept='IT', salary=1000}
Employee{id=3, name='Rose', dept='Admin', salary=4000}
Employee{id=4, name='Sara', dept='Admin', salary=3500}
Employee{id=5, name='Tanaka', dept='IT', salary=3000}
Employee{id=6, name='Charlie', dept='IT', salary=4500}
-- finding all EmployeeSalary --
Name: Diana, Salary: 3000
Name: Mike, Salary: 1000
Name: Rose, Salary: 4000
Name: Sara, Salary: 3500
Name: Tanaka, Salary: 3000
Name: Charlie, Salary: 4500
-- finding the EmployeeSalary in IT dept --
Name: Mike, Salary: 1000
Name: Tanaka, Salary: 3000
Name: Charlie, Salary: 4500

Example Project

Dependencies and Technologies Used:

  • spring-data-jpa 2.0.9.RELEASE: Spring Data module for JPA repositories.
    Uses org.springframework:spring-context version 5.0.8.RELEASE
  • hibernate-core 5.3.5.Final: Hibernate's core ORM functionality.
    Implements javax.persistence:javax.persistence-api version 2.2
  • h2 1.4.197: H2 Database Engine.
  • JDK 1.8
  • Maven 3.5.4

Interface-based Projections Select All Download
  • spring-data-jpa-interface-based-projections
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • EmployeeRepository.java
          • resources
            • META-INF

    See Also