Spring Data JPA Projections – 5 ways to return custom response

Spring-Data-JPA-Projections

Share this:
  • 2
  •  
  •  
  • 1
  •  
  •  
    3
    Shares

In this article, we are going to see Projections in Spring Data JPA in detail. We will see what are different types of projections and what are use cases to use them.

Table of Contents

What is Projection?

If you already know about Spring Data JPA, you must be knowing that all the query methods of Repository classes will return an entity object. There may be cases where we do not want an entire entity from the query method. We may be interested only in few attributes of that entity or subset of that entity with some manipulation in it. In those cases, we will be using Projection which projects us only the required data out of entire entity class.

Broadly there are two types of projections, Interface-based Projections, and Class-based Projections. Let’s see them in detail.

Interface-based Projections

As the name implies we are going to use an interface here. In this type, we create an interface with only getter methods of properties we want from an entity class. This interface will be the return type of query method we write in Spring Data JPA’s Repository interface. It has the following three types:

Close Projection

In Close Projection, the getter methods of interface match exactly with the getter methods of Entity’s properties. For example, consider you have an entity of Employee table as follows:

Now if we are interested only in Id, First Name, Last Name and Department Name of Employee, we will create an Interface as follows:

To make use of it, use this interface as a return type of query method in your Repository interface:

Open Projection

In Open Projection we will create an interface with getter methods of selective properties only but in addition to that, we also use SpEL expression. The SpEL expression will help us to define a new property from existing properties. Like in the above case if we want a property “fullName” then we can define it using SpEL expression and @Value  annotation. Likewise, we can also define a new property from nested property of entity class. In our case, we can define department name property from the hierarchy of Employee and Department entity.

If you don’t want to use SpEL expression, you can define default methods in the projection type interface to achieve the same thing.

Dynamic Projection

It is possible to define what projection type to return from the query method at runtime. To achieve this, just include a new argument to query method of type Class and set it with your projection type as follows:

From the Service class, invoke the repository method as follow:

Class-based Projections

In Interface-based Projection, we were creating interfaces with getter methods. If you were thinking about Classes in Class-based Projections, then you are absolutely correct. We create Projection class which contains only those properties we were interested in the Entity class and its class hierarchy. You can create the instance of your custom projection class using argument constructor or a Map.

Projection with argument constructor

In argument constructor way, we create the instance of projection class in the JPQL itself. Consider your projection class is as follows:

In JPA Repository we will use above constructor in JPQL to return its object as a response to repository method:

Result in Map format

In some cases, our Projection class contains a large number of properties and we may want to use the same class for different requirements which requires different sets of properties. Creating a new constructor with a number of arguments for all such requirements may not be a good practice. In such situations, we add a constructor in our Projection class with a Map. The Map contains alias of selected property as a key(string) and its value. Though we use the same projection class, only interested properties will be set here.

In JPQL of repository method, use the alias while selecting a property of Entity and define the List of Map as return type.

The service method will get the projection class’s objects from the result of a repository method using a constructor with Map as follows:

That’s all about Projections in Spring Data JPA.

Source Code

The source code of examples shown in this article is available on Github.

 


Share this:
  • 2
  •  
  •  
  • 1
  •  
  •  
    3
    Shares