我有一个Product对象,其中包含相关产品列表(也是产品对象)。相关产品领域的注释如下:
public class Product {
@JoinTable(name = "RELATED_PRODUCT", joinColumns = {
@JoinColumn(name = "PRODUCT_ID", referencedColumnName = "id", nullable = false)}, inverseJoinColumns = {
@JoinColumn(name = "RELATED_PRODUCT_ID", referencedColumnName = "id", nullable = false)})
@ManyToMany(fetch = FetchType.LAZY)
List<Product> relatedProducts;
}
正如你所看到的那样,列表是懒惰的,这在大多数情况下都是我想要的。但是,在某些情况下,我希望立即填写相关产品清单。我用LEFT JOIN FETCH为此创建了一个查询。但是,我只想添加具有一定评级的相关产品,假设评级为&gt; 3。
我尝试了以下内容:
SELECT DISTINCT p FROM Product p LEFT JOIN FETCH p.comparableProducts cp WHERE p.id = :id AND cp.rating > 3 AND CURRENT_DATE BETWEEN p.commenceDate AND p.removeDate
但这不起作用。它总是返回数据库中的所有相关产品,而不仅仅是那些评级高于3的产品。这是如何解决的?
答案 0 :(得分:1)
解决此问题的最简单方法是单独加载相关产品,而不是尝试将它们放入relatedProducts
字段。
从面向对象的角度来看,这也很有意义。我想你有类似“产品页面”的东西,其中包含所选产品和“推荐产品”。如果是这样,这样的页面是一个独立的概念,值得拥有自己的类:
public class ProductPage {
private Product product;
private List<Product> recommendedProducts;
...
}
然后你可以通过一个查询填写这样一个类:
SELECT DISTINCT p, cp FROM Product p LEFT JOIN p.comparableProducts cp WHERE p.id = :id AND cp.rating > 3 AND CURRENT_DATE BETWEEN p.commenceDate AND p.removeDate
或通过两个单独的查询。
不幸的是,这种方法不允许您直接从JPA接收ProductPage
的实例,您需要手动编写转换代码。