1

技术: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。

如何以最佳方式解决问题?

4

0 回答 0