约束JPA中JOIN FETCH返回的行数

时间:2013-12-03 19:38:13

标签: jpa jpql

我有一个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的产品。这是如何解决的?

1 个答案:

答案 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的实例,您需要手动编写转换代码。