Проблема N + 1 во множестве к одному с предложением IN - PullRequest
0 голосов
/ 07 февраля 2020

У меня есть две сущности с однонаправленным отношением многие-к-одному, как показано ниже:

class CarMaster {
       // some properties
       @Column(name = "CAR_ID")
       private Long carId;
}

class CampaignMapping { 
    // other properties
    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "CAR_ID", referencedColumnName = "CAR_ID")
    private CarMaster carMaster;

    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "CONTRACT_ID", referencedColumnName = "CONTRACT_ID")
    private ContractMaster contractMaster;
}

У меня есть запрос ниже, в котором я ищу CampaignMapping, соответствующий списку идентификаторов автомобилей.

@Override
public List<CampaignMapping> findByCarMasterCarId(final Long carIds) {
    final CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder();
    final CriteriaQuery<CampaignMapping> criteriaQuery = criteriaBuilder
            .createQuery(CampaignMapping.class);
    final Root<CampaignMapping> campaignMappingRoot = criteriaQuery
            .from(CampaignMapping.class);
    // below line didn't help
    //campaignMappingRoot.fetch("carMaster");
    campaignMappingRoot.fetch("contractMaster");
    criteriaQuery.select(CampaignMappingRoot);
    // I guess issue is with this line
    // causing N queries
    criteriaQuery.where(criteriaBuilder.equal(
            campaignMappingRoot.get("carMaster").get("carId"),
            carIds));
    return this.entityManager.createQuery(criteriaQuery).getResultList();
}

Я ожидал получить результат в одном запросе с предложением IN. Я проверил журналы гибернации, и он печатает 1 запрос select с предложением IN, имеющим все идентификаторы, и запросы select для каждого для каждого идентификатора машины в списке с условием равенства. Я пробовал с FetchType.EAGER и campaignMappingRoot.fetch("carMaster");, но количество выполненных запросов осталось прежним. Подскажите, пожалуйста, как получить результат без проблемы N + 1, используя только запрос CriteriaBuilder.

...