JPA Projections

Overview

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.

The problem

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:

JPA practices
Methodology Pros Cons

Eager loading

The relationships among the entities are resolved by reading the dependences of an entity when reading the entity.
This is acomplished via database joins.
  • Coding is easy, as all data is always ready to use
  • Terrible performance

Lazy loading

The 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.
  • Good performance for simple queries
  • Not optimal performance as joins are not implicitely used. See N + 1 problem.
  • To improve performance eager fetching is explicitely requested for some queries, but this ends on more and more complex code when many different queries are needed.

Open Session In View pattern

The 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.
  • Only used date is read from database
  • Good performance
  • Breaks the 3-tier separation
  • Impossibility of caching data in middle tiers

Our proposal

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.

JPA projection practice
Methodology Pros Cons

JPA Projections

A projection is defined for each different view needed from an entity.
  • Very simple code
  • Optimal performance for queries
  • Not suitable for complex needs

An example

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;