Class-based Projections (DTOs)

Another way of defining projections is by using value type DTOs (Data Transfer Objects) that hold properties for the fields that are supposed to be retrieved. These DTO types can be used in exactly the same way projection interfaces are used, except that no proxying happens and no nested projections can be applied.

If the store optimizes the query execution by limiting the fields to be loaded, the fields to be loaded are determined from the parameter names of the constructor that is exposed.

The following example shows a projecting DTO:

Example 1. A projecting DTO
class NamesOnly {

  private final String firstname, lastname;

  NamesOnly(String firstname, String lastname) {

    this.firstname = firstname;
    this.lastname = lastname;
  }

  String getFirstname() {
    return this.firstname;
  }

  String getLastname() {
    return this.lastname;
  }

  // equals(…) and hashCode() implementations
}
Avoid boilerplate code for projection DTOs

You can dramatically simplify the code for a DTO by using Project Lombok, which provides an @Value annotation (not to be confused with Spring’s @Value annotation shown in the earlier interface examples). If you use Project Lombok’s @Value annotation, the sample DTO shown earlier would become the following:

@Value
class NamesOnly {
	String firstname, lastname;
}

Fields are private final by default, and the class exposes a constructor that takes all fields and automatically gets equals(…) and hashCode() methods implemented.