1

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?

Oleg
  • 11
  • 1

0 Answers0