2012-03-29 30 views
2

我有一個一對多的關係:HQL:像空關係

public class Class1{ 

    private String attr1; 
    private String attr2; 

    @OneToOne 
    private Class2 object1; 

} 

public class Class2{ 
    private String attr3;  
} 

的關係可以存儲空對象(我的意思是1類的一個實例可以在object1空)。我想做一個完整的搜索中的所有屬性,所以我創造了這個的HQL查詢:

SELECT p FROM Class1 p 
WHERE 
(
upper(p.attr1) LIKE :filter OR 
upper(p.attr2) LIKE :filter OR 
upper(p.object1.attr3) LIKE :filter 
) 

和我之前和之後通過一個String PARAM以大寫爲「%」:

query.setParameter("filter", "%"+filter.trim().toUpperCase()+"%"); 

它工作正常,但對於object1 = null的實體。它從來沒有得到這些實體。事實上,如果我刪除最後一個條件(上(p.object1.attr3)LIKE:過濾器)它的作品,但我需要包括它。

我有,雖然我應該做一個LEFT JOIN與關係,所以我一直試圖把它寫成:

SELECT p FROM Class1 p LEFT JOIN p.object1 AS p1 
WHERE 
(
upper(p.attr1) LIKE :filter OR 
upper(p.attr2) LIKE :filter OR 
upper(p1.attr3) LIKE :filter 
) 

或類似

SELECT p FROM Class1 p LEFT JOIN p.object1 AS p1 
WHERE 
(
upper(p.attr1) LIKE :filter OR 
upper(p.attr2) LIKE :filter OR 
(p1 is not null AND upper(p1.attr3) LIKE :filter) 
) 

,但沒有成功。

有什麼想法?

謝謝。

回答

2

據我瞭解你所需要的值或者p1.attr3 is null,當它是not null應該驗證的條件。所以,我只是微調你的最後一個查詢;

SELECT p FROM Class1 p LEFT JOIN p.object1 AS p1 
WHERE 
(
upper(p.attr1) LIKE :filter OR 
upper(p.attr2) LIKE :filter OR 
(p1.attr3 is null OR upper(p1.attr3) LIKE :filter) 
) 
+0

正如你所看到的,我留下的問題是另一個問題。所以你的回答是可以的(儘管它甚至不需要檢查p1是否爲空) – Javi 2012-03-29 12:36:11

2

您必須使用外連接!

例如:

SELECT p FROM Class1 p OUTER JOIN p.object1 AS p1 
    WHERE ... ; 
+0

我發現了這個問題。這不是我需要一個外部連接。我有兩個查詢一個用於計數,另一個用於選擇,我只是改變了選擇中的左連接。但謝謝你的建議。 – Javi 2012-03-29 12:33:40

2
SELECT p FROM Class1 p 
WHERE 
upper(p.attr1) LIKE :filter OR 
upper(p.attr2) LIKE :filter OR 
UNION 
SELECT p FROM Class1 p LEFT JOIN p.object1 AS p1 
WHERE 
upper(p1.attr3) LIKE :filter 
+1

雖然有效,但效率不高。每當使用UNION時,數據庫必須完成一個完整的結果集(這就是爲什麼建議避免使用UNION或者更喜歡UNION ALL--但這裏UNION ALL不正確)。外連接是處理這種情況的有效方式。 PLS。看到我的迴應。 – Johanna 2012-03-29 12:32:15

+0

我發現了這個問題。我有兩個查詢一個用於計數,另一個用於選擇,我只是改變了選擇中的左連接。所以不需要做一個工會,它沒有它的工作。但是,謝謝。 – Javi 2012-03-29 12:34:25