Я довольно новичок в Hibernate и Criteria API и сталкиваюсь с проблемами при их использовании.
Есть две сущности:
@Entity
public class Product {
@Id
@GeneratedValue
private Integer id;
private String productName;
@OneToMany(fetch = FetchType.LAZY,
cascade = CascadeType.ALL)
private List<ProductPrice> prices = new ArrayList<>();
}
@Entity
public class ProductPrice {
@Id
@GeneratedValue
private Integer id;
private BigDecimal price;
private String region;
private LocalDate startDate;
}
Продукты имеют несколько ProductPrices. Каждая ProductPrice принадлежит Региону. Цель состоит в том, чтобы запросить продукты и все их исторические цены для определенного c региона:
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Product> cq = cb.createQuery(Product.class);
Root<Product> root = cq.from(Product.class);
ListJoin<Product, ProductPrice> productJoin = root.join(Product_.prices, JoinType.INNER);
productJoin.on(cb.equal(productJoin.get(ProductPrice_.region), "REGION1"));
List<Product> products = em.createQuery(cq.distinct(true)).getResultList();
. Это генерирует следующий запрос SQL:
select
distinct product0_.id as id1_1_,
product0_.productName as productN2_1_
from
Product product0_
inner join
(
Product_ProductPrice prices1_
inner join
ProductPrice productpri2_
on prices1_.prices_id=productpri2_.id
)
on product0_.id=prices1_.Product_id
and (
productpri2_.region=?
)
Я пробовал этот запрос и, похоже, это работает, однако, как только getPrices()
вызывается для одного из Продуктов, Цены на Продукт лениво выбираются, например:
select
prices0_.Product_id as Product_1_2_0_,
prices0_.prices_id as prices_i2_2_0_,
productpri1_.id as id1_3_1_,
productpri1_.price as price2_3_1_,
productpri1_.region as region3_3_1_
from
Product_ProductPrice prices0_
inner join
ProductPrice productpri1_
on prices0_.prices_id=productpri1_.id
where
prices0_.Product_id=?
, что имеет смысл из-за ассоциации @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
, но в этом случае для этого конкретного c запроса я не хочу такого поведения. Я не нашел подобного примера в Hibernate UserGuide или здесь, в stackoverflow, так что я предполагаю, что упускаю что-то очень очевидное. Но все же я не смог найти решение своей проблемы.
Спасибо!