技术:Spring Data、QueryDSL
有一个实体与实体图和三个不包含在实体图中的集合
@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;
当我调用 JPA Repository 方法时:
@Override
@EntityGraph(value = "companySale-fetch-all")
Page<CompanySale> findAll(Predicate predicate, Pageable pageable);
它工作正常并返回包含三个未包含在 entityGraph 中的集合的数据。
但是要实现指定的排序,我必须实现另一个存储库方法:
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);
它从 db 返回数据,但是当映射器尝试获取未包含在 entityGraph 中的三个集合中的任何一个时,我遇到了异常:
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,
在 IDEA 调试中,它看起来像:无法评估表达式方法抛出 'org.hibernate.exception.GenericJDBCException' 异常。
我尝试用 FetchType.SELECT 替换 FetchType.SUBSELECT。它有效,但会导致 n+1 问题。
我试图将此集合添加到 entityGraph,但得到了 MultipleBadException。
如何以最佳方式解决问题?