У меня есть две сущности с однонаправленным отношением многие-к-одному, как показано ниже:
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
.