JPA - Basic Projections
Projection is a subset of entities' properties, represented as dedicated class(es), and mapped either as the database view based entity, or using constructor expressions.
Join the DZone community and get the full member experience.
Join For FreeIn my last post: JPA - Should I become a laziness extremist? - I mentioned about the possibilities of improving JPA usage - one of them is using Projections.
Projection is a subset of entities' properties. It can be represented as dedicated class (or classes), and mapped either as the database view based entity, or using constructor expressions [1][2]. The clue of this solution is having very limited entities tree (or no tree at all, as in my example) comparing to original entity (Employee). We need to display employee name, thus we build the projection having employee name and ID only. As you will see below, using projections leads to single SQL query, instead of bunch of SQL queries (see example in JPA - Should I become a laziness extremist?)
Database view based entities
What we need in this case is simple JPA entity, mapped to any database view (or table if desired properties are in one table).
package com.blogspot.vardlokkur.domain;
import java.io.Serializable;
import javax.annotation.concurrent.Immutable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Immutable
@Table(name = "EMPLOYEE")
public class ViewBasedEmployeeNameProjection implements Serializable {
@Column(name = "EMPLOYEE_ID")
@Id
private Long employeeId;
@Column(name = "EMPLOYEE_NAME")
private String name;
ViewBasedEmployeeNameProjection() {
super();
}
public Long getEmployeeId() {
return employeeId;
}
public String getName() {
return name;
}
}
Now we can run JPQL query: select employee from ViewBasedEmployeeNameProjection employee order by employee.name
Constructor expressions
What we need in this case is a class representing the projection with constructor having parameters corresponding to all properties in the projection.
package com.blogspot.vardlokkur.domain;
import java.io.Serializable;
import javax.annotation.concurrent.Immutable;
@Immutable
public class EmployeeNameProjection implements Serializable {
private final Long employeeId;
private final String name;
public EmployeeNameProjection(Long employeeId, String name) {
super();
this.employeeId = employeeId;
this.name = name;
}
public Long getEmployeeId() {
return employeeId;
}
public String getName() {
return name;
}
}
Now we can run JPQL query:
which in turn will execute one single SQL query:
This method has some disadvantages:
- adding new projection properties increases number of constructor parameters
- projection class name is included in JPQL query, which may lead to refactoring problems
To be continued ...
Few links for the dessert
Published at DZone with permission of Michal Jastak, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Trending
-
Strategies for Reducing Total Cost of Ownership (TCO) For Integration Solutions
-
How To Use Pandas and Matplotlib To Perform EDA In Python
-
Manifold vs. Lombok: Enhancing Java With Property Support
-
A Deep Dive Into the Differences Between Kafka and Pulsar
Comments