Spring Data JPA - Projections Using Default Methods

[Updated: Aug 29, 2018, Created: Aug 29, 2018]

As an alternative to projection interface having methods with SpEL, we can use Java 8 default methods for custom logic.

Quick Example

public interface EmployeeInfo {
  String getName();
  Department getDepartment();
  default String getDisplayString() { //custom logic
      return String.format("Name: %s, Dept: %s", getName(),

Complete Example


public class Employee {
  private Integer id;
  private String name;
  @ManyToOne(cascade = CascadeType.ALL)
  private Department department;
  private int salary;
public class Department {
  private Integer id;
  private String deptName;
  private String location;

Projection interface using default method

public interface EmployeeInfo {
  String getName();
  Department getDepartment();
  default String getDisplayString() {
      return String.format("Name: %s, Dept: %s", getName(),


public interface EmployeeRepository extends CrudRepository<Employee, Long> {
  List<EmployeeInfo> findBy();

Example Client

public class ExampleClient {

  private EmployeeRepository repo;

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

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

      System.out.println("-- All EmployeeInfo --");
      List<EmployeeInfo> list = repo.findBy();
      System.out.println("-- display strings --");
      list.forEach(employeeInfo -> System.out.println(employeeInfo.getDisplayString()));

  private List<Employee> createEmployees() {
      return Arrays.asList(
              Employee.of("Diana", Department.of("Admin", "NY"), 3000),
              Employee.of("Mike", Department.of("IT", "TX"), 35000),
              Employee.of("Rose", Department.of("Sales", "NC"), 4000),
              Employee.of("Sara", Department.of("Admin", "TX"), 3500),
              Employee.of("Joe", Department.of("IT", "TX"), 3000),
              Employee.of("Charlie", Department.of("IT", "NY"), 4500)

Main method

public class ExampleMain {

  public static void main(String[] args) {
      AnnotationConfigApplicationContext context =
              new AnnotationConfigApplicationContext(AppConfig.class);
      ExampleClient exampleClient = context.getBean(ExampleClient.class);;
      EntityManagerFactory emf = context.getBean(EntityManagerFactory.class);
-- finding all employees --
Employee{id=1, name='Diana', department=Department{id=2, deptName='Admin', location='NY'}}
Employee{id=3, name='Mike', department=Department{id=4, deptName='IT', location='TX'}}
Employee{id=5, name='Rose', department=Department{id=6, deptName='Sales', location='NC'}}
Employee{id=7, name='Sara', department=Department{id=8, deptName='Admin', location='TX'}}
Employee{id=9, name='Joe', department=Department{id=10, deptName='IT', location='TX'}}
Employee{id=11, name='Charlie', department=Department{id=12, deptName='IT', location='NY'}}
-- All EmployeeInfo --
-- display strings --
Name: Diana, Dept: Admin
Name: Mike, Dept: IT
Name: Rose, Dept: Sales
Name: Sara, Dept: Admin
Name: Joe, Dept: IT
Name: Charlie, Dept: IT

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

Projections Using Default Methods Select All Download
  • spring-data-jpa-projection-using-default-methods
    • src
      • main
        • java
          • com
            • logicbig
              • example
          • resources
            • META-INF

    See Also