2013-12-03 17 views
1

我正在使用Product對象以及相關產品(它們也是產品對象)的列表。相關產品領域的註解如下:約束JPA中JOIN FETCH返回的行數

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創建了一個查詢。不過,我想只能添加了相關的產品,有一定的等級,讓我們說的> 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

解決此問題的最簡單方法是單獨加載相關產品,而不是試圖將它們安裝到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的實例,您需要手動編寫轉換代碼。

+0

嗯...... JPA無法做到這一點或我在這裏錯了嗎?我認爲將產品對象添加到評級> 3的列表並不困難。畢竟,這種機制可以在沒有獲取的情況下使用(即:我可以獲取具有「原始」產品的產品評分> 3),也是SQL的一部分。我相信你,當你說你的答案是我的問題的解決方案時,但這看起來很麻煩。我只想要一款包含相關產品的產品。它們是該特定產品的一部分,所以即使從面向對象的角度來看,它們也應該屬於它。 – Niles11

+0

重點在於它從某種意義上說是JPA的精神,因爲JPA假設持久字段的狀態反映數據庫的狀態。 – axtavt

+0

是的,我同意這一點,但我的情況似乎是任何程序員都可以進入的。只是一個典型的關係問題。我真的認爲這樣做會有一個很好和乾淨的方式,但不幸的是沒有。看來我必須接受這一點。無論如何感謝您的答案! – Niles11