Projections
Fetching entities from the database comes with a performance cost:
- it typically involves fetching all columns from one or more tables - even if only some parts of entity is needed - this consumes database resources and network bandwidth between application and the database server
- fetched entity is added to persistence context - which occupies application memory - and becomes a subject of dirty checking - which consumes CPU cycles
While fetching complete entity often makes sense when an entity needs to be updated, the overall agreement between Java/DB experts is that when data is needed only for reading, projections should be fetched instead of entities.
What is a projection?
Projection is a concept of fetching only a part of an entity needed for a specific use case. It is a concept very natural when working with pure SQL - as why would you query for more data than you need, but it is not trivial when working with ORM like JPA.
There are multiple approaches on projections can be fetched with JPA, Hibernate and Spring Data JPA - they all come with important to understand tradeoffs.
Setting the stage
In this guide we are going to work with a database for movies website like IMDB.
The basic entity we are going to work first is a Movie
- that maps to a database table containing basic information about movies.
package com.example.projections;
@Entity
public class Movie {
@Id
private String id;
private String title;
private int year;
private String description;
// ..
}
While most of its columns is small, it contains a description
column that contains potentially large amounts of text. How large? Large enough to choose to skip it to save network bandwidth.