Technology: Spring Data, QueryDSL
There is an entity with entity graph and three collections which not included in entity graph
@NamedEntityGraphs({
@NamedEntityGraph(
name = "companySale-fetch-all",
attributeNodes = {
@NamedAttributeNode("responsible"),
@NamedAttributeNode(value = "mainContact", subgraph = "mainContact-subgraph"),
@NamedAttributeNode("companySaleGoogleAdRecord"),
@NamedAttributeNode("companySaleCreateSource"),
@NamedAttributeNode(value = "company", subgraph = "company-subgraph"),
@NamedAttributeNode("source"),
@NamedAttributeNode("firstActivity"),
@NamedAttributeNode("lastActivity"),
@NamedAttributeNode("favoriteToEmployees")
},
subgraphs = {
@NamedSubgraph(
name = "company-subgraph",
attributeNodes = {
@NamedAttributeNode("responsible")
}
),
@NamedSubgraph(
name = "mainContact-subgraph",
attributeNodes = {
@NamedAttributeNode("socialNetworkUser")
}
)
}
)
})
public class CompanySale {
/**
* List of applications for resume for sale.
*/
@OneToMany(mappedBy = "companySale")
@Fetch(FetchMode.SUBSELECT)
@EqualsAndHashCode.Exclude
@ToString.Exclude
private List<ResumeRequest> resumeRequests;
/**
* List of applications for evaluation for sale.
*/
@OneToMany(mappedBy = "companySale")
@Fetch(FetchMode.SUBSELECT)
@EqualsAndHashCode.Exclude
@ToString.Exclude
private List<EstimationRequest> estimationRequests;
@ManyToMany
@JoinTable(name = "crm_company_sale_tag",
joinColumns = @JoinColumn(name = "company_sale_id"),
inverseJoinColumns = @JoinColumn(name = "tag_id"))
@Fetch(FetchMode.SUBSELECT)
@EqualsAndHashCode.Exclude
@ToString.Exclude
private List<Tag> tags;
When i call JPA Repository method:
@Override
@EntityGraph(value = "companySale-fetch-all")
Page<CompanySale> findAll(Predicate predicate, Pageable pageable);
It works fine and return data with three collections not included in entityGraph.
BUT to implement specified sort i had to implement another repository method:
public Page<CompanySale> customRequest(Predicate predicate, Pageable pageable) {
final EmployeeUser authenticatedUser = (EmployeeUser)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
QCompanySale qCompanySale = QCompanySale.companySale;
JPAQueryFactory jpaQueryFactory = new JPAQueryFactory(entityManager);
final EntityGraph<?> entityGraph = entityManager.getEntityGraph("companySale-fetch-all");
final List<CompanySale> companySaleQueryResults = jpaQueryFactory
.select(qCompanySale)
.from(qCompanySale)
.setHint("javax.persistence.fetchgraph", entityGraph)
.where(predicate)
.orderBy(Expressions.asNumber(new CaseBuilder().when(qCompanySale.favoriteToEmployees.contains(authenticatedUser.getId())).then(2).otherwise(1)).desc(), qCompanySale.status.asc(), qCompanySale.createDate.desc())
.limit(pageable.getPageSize())
.offset((long) pageable.getPageNumber() * pageable.getPageSize())
.fetch();
return new PageImpl<>(companySaleQueryResults, pageable, 25);
It returns data from db, but when mapper tries to get any of three collections which not included in entityGraph i got exception:
org.hibernate.exception.GenericJDBCException: could not load collection by subselect: [com.andersenlab.crm.model.entities.CompanySale.resumeRequests#<112370, 136943, 136942, 130798, 112366, 136941, 112374, 136949, 112352, 112350, 112349, 112358, 136980, 112403,
In IDEA debug it looks like: Unable to evaluate the expression Method threw 'org.hibernate.exception.GenericJDBCException' exception.
I tryed to replace FetchType.SUBSELECT with FetchType.SELECT. It's works, but lead to n+1 issue.
I tried to add this collections to entityGraph, but got MultipleBadException.
How to solve issue in optimal way?