Spring Data Projection

Spring Data query methods usually return one or multiple instances of the aggregate root managed by the repository. However, it might sometimes be desirable to create projections based on certain attributes of those types. Spring Data allows modeling dedicated return types, to more selectively retrieve partial views of the managed aggregates.

Projection is just a way to retrieve certain fields from the database without retrieving all fields. This improves performance as it does not retrieve all fields.

There are 3 different types of projection: Scalar, DTO, Entity projection

Scalar Projection

Scalar projection allows you to select columns you need.

@Repository
public interface BookRepository extends JpaRepository<User, Long> {
 
    @Query("SELECT u.name, u.email FROM Book b")
    List<Object[]> getNameAndEmail();   
}

DTO Projection

DTO projection uses a constructor which Hibernate uses to populate data from the database.

@Repository
public interface UserRepository extends CrudRepository<User, Long> {
 
    @Query("SELECT new com.kaveinga.user.dto.UserDetailDTO(u.firstName, u.lastName) FROM User user WHERE user.firstName = :firstName")
    List<UserDetailDTO> findByFirstName(String firstName);
}

JPA DTO

As long as the DTO class has only one constructor and its parameter names match your entity class’s attribute names, Spring generates a query with the required constructor expression.

public interface UserRepository extends JpaRepository<User, Long> {
    UserDTO findByEmail(String email);

}
public class UserDTO {

    private Long       id;

    private String     uid;

    private String     name;

    private String     email;

    private int        age;

    private Address address;

    public UserDTO(Long id, String uid, String name, String email, int age, Address address) {
        super();
        this.id = id;
        this.uid = uid;
        this.name = name;
        this.email = email;
        this.age = age;
        this.address = address;

    }

    // getters and setters
}

JPA DTO as interface

Here is another way you can retrieve data from the database. Instead of having a DTO class you can use an interface. Your interface only defines getter methods for basic attributes.

public interface UserRepository extends JpaRepository<User, Long> {

    UserView findByUid(String uuid);

}
public interface UserView {

    Long getId();

    String getName();

    String getEmail();

    int getAge();

    String getUid();
    // nested object
    AddressView getAddress();

}

 




Subscribe To Our Newsletter
You will receive our latest post and tutorial.
Thank you for subscribing!

required
required


Leave a Reply

Your email address will not be published.