I am running into a strange issue with JPA/Hibernate I hope I can get some help with. My environment:
I am using two Entities:
@Entity
@Table(name = "\"accUser\"")
public class User implements Serializable {
private static final long serialVersionUID = -5750077342980986498L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "UserID")
private Long id;
// NOTE: Below is an embedded object!
@OneToOne
@JoinColumn(name = "EmpNum")
private Employee employee;
//...other fields are wrapped primitives omitted for brevity
}
@Entity
@Table(name = "\"hrmEmployee\"")
public class Employee implements Serializable {
private static final long serialVersionUID = 5471137977607643256L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "EmpNum")
private Long employeeNumber;
@Column(name = "FirstName")
private String firstName;
//...other fields are wrapped primitives omitted for brevity
}
I have the following (closed) Projection interfaces defined, each in their own class file:
@Projection(types={ User.class })
interface UserProjection {
Long getId();
EmployeeFirstNameProjection getEmployee();
}
@Projection(types={ Employee.class })
interface EmployeeFirstNameProjection {
String getFirstName();
}
I am calling this Repository interface query method:
<T> T findUserById(Long id, Class <T> type);
And calling the above Repository method with this Service method:
public UserProjection getUser(Long id) {
return userRepository.findUserById(id, UserProjection.class);
}
So at runtime, here is the JSON of the single returned UserProjection:
{"employee":{"firstName":"Matt"},"id":1796}
This is exactly what I want to be returned. However, when the code executes, Hibernate is selecting all fields in both entities in two queries, which I don't want. The whole reason I am using the Projections mechanism is to limit wire traffic with the JSON, and also want to hopefully keep the number of queries low for performance reasons.
What I expect is to see a SINGLE Hibernate generated query.
Why is Hibernate running two respective queries that select every field in each of the entities?
Thanks in advance!
Hibernate and Spring-data are working as they should, when there is a non primitive field in the projection all the columns are included in the query.
It was already explained here https://stackoverflow.com/a/53783270/3449039 and a jira was opened at that moment https://jira.spring.io/browse/DATAJPA-1218 and closed with this answer "Currently, we don't optimize the query for referenced entities by only selecting the required properties".
As workaround you could create a JPQL query with a custom DTO or try something like Blaze-Persitence as was mentioned by @christian-beikov