This library introduces the concept of entity projections. A projection is a class with a subset of the fields of a JPA Entity.
JPA Projections library provides some utilities to manage projections easily with minimal code.
Object-Relational mapping frameworks (ORM) have become more and more popular in the last years. In Java EE the Java Persistence API (JPA) was the standarization of the technique.
ORMs provide a very productive environment in the short-time, but it has downsides where
the application gets bigger. The usual main issues are complexity and performance.
It is very difficult to have a large-scale application using JPA without facing performance
problems and without writing a great amount of code in the persistence layer.
There are the following approaches when writing complex JPA code:
Methodology | Pros | Cons |
---|---|---|
Eager loadingThe relationships among the entities are resolved by reading the dependences of an entity when reading the entity.This is acomplished via database joins. |
|
|
Lazy loadingThe relationships among the entities are resolved deferring the reading of the dependences of the entity.When dependencies are needed, an additional select is triggered against the database. |
|
|
Open Session In View patternThe JPA session remains open in the whole request, including renderization of user interface. The majority of entities are configured for lazy-loading, so only used data is read from database.See OSIV in the Hibernate documentation. |
|
|
JPA projections propone to have different projections of an entity for each different need.
Defining a projection is a trivial task consisting in declaring the fields from an entity that you are going to use.
For each projection, JPA projection library provides methods to make selections and updates with minimal code.
Methodology | Pros | Cons |
---|---|---|
JPA ProjectionsA projection is defined for each different view needed from an entity. |
|
|
The JPA entity (not all code is shown):
@Entity public class User { @Id @GeneratedValue private Integer id; private String username; private String password; private boolean enabled; @ElementCollection(fetch = FetchType.EAGER) @Enumerated(EnumType.STRING) private Set<Role> roles; ... // getters and setters }
A projection to show user names (all code is shown):
@EntityProjection public class Username extends Projection { private Integer id; private String username; }
An example query:
ProjectionDAO<User, Username> usernameDAO = projectionDAOFactory.forEntityAndProjection(User.class, Username.class); List<Username> usernames = usernameDAO.findAll();
The previous query performs the following select against the database:
SELECT id, username FROM user;