2011-07-06 78 views
1

我試圖讓下面的查詢在Hibernate中工作的評價:休眠:條件查詢不正確

SELECT m FROM MyEntity m WHERE m.owner = :user 
         AND m.field1 IN (:field1Vals) 
         AND m.field2 IN (:field2Vals) 
         AND m.obj1 IS NOT NULL 
         AND (
           m.obj1.count > 0 
          OR 
           (m.obj2 IS NOT NULL 
            AND m.obj2.count > 0) 
          ) 
         ORDER BY m.createDate DESC 

的問題是,它似乎始終評估就是那張在部分:

AND (
     m.obj1.count > 0 
    OR 
     (m.obj2 IS NOT NULL 
     AND m.obj2.count > 0) 
) 

...爲:

AND (m.obj2 IS NOT NULL 
    AND m.obj2.count > 0) 

換句話說,它僅返回滿足條件的對象使得f忽略了OR,並忽略滿足第一個條件的任何結果。如果我刪除OR之後的條件,則查詢會正確地返回滿足m.obj1.count > 0條件的對象。

我假設我已經在我的查詢結構中做了一些基本的錯誤,但我不確定它會是什麼。有任何想法嗎?

更新

我發現一個可行的變型,它採用了自連接,並增加了一些多餘的括號:

SELECT DISTINCT m FROM MyEntity m, MyEntity m2 WHERE m.owner = :user 
               AND m.field1 IN (:field1Vals) 
               AND m.field2 in (:field2Vals) 
               AND m.obj1 IS NOT NULL 
               AND (
                 (m.obj1.count > 0) 
                OR 
                 (m2.obj2 IS NOT NULL 
                 AND (m2.obj2.count > 0)) 
                ) 
               ORDER BY m.createDate DESC" 

這不相同的查詢自聯接不工作。看似多餘的括號也一樣。有了它們,它會返回不正確的結果。

所以現在我的問題是,爲什麼有必要這樣構造查詢,既關於自連接和「多餘的」括號?

值得注意的是obj1obj2是同一個外部實體的不同實例。所以我查詢的表是在一個外部表中引用兩個不同的行。我懷疑這就是爲什麼自聯接是必要的(這也是我決定嘗試自聯接的原因),但我不確定它背後的原因是什麼。任何解釋都會受到歡迎。

回答

0

爲了解決這個問題,我最終不得不如下修改我的查詢:

SELECT DISTINCT m FROM MyEntity m, MyEntity m2 WHERE m.owner = :user 
               AND m.field1 IN (:field1Vals) 
               AND m.field2 in (:field2Vals) 
               AND m.obj1 IS NOT NULL 
               AND (
                 (m.obj1.count > 0) 
                OR 
                 (m2.obj2 IS NOT NULL 
                 AND (m2.obj2.count > 0)) 
                ) 
               ORDER BY m.createDate DESC 

我感謝蘭迪因爲他的建議非常好,但在我的具體情況下,它並不奏效,爲了得到正確的結果,我必須使用自連接來重寫原始查詢。

1

看起來驗貨OK ......你可以試試這個方法冗長:

SELECT m FROM MyEntity m WHERE m.owner = :user 
         AND m.field1 IN (:field1Vals) 
         AND m.field2 IN (:field2Vals) 
         AND m.obj1 IS NOT NULL 
         AND (
           m.obj1.count > 0 
          ) 
union 
SELECT m FROM MyEntity m WHERE m.owner = :user 
         AND m.field1 IN (:field1Vals) 
         AND m.field2 IN (:field2Vals) 
         AND m.obj1 IS NOT NULL 
         AND  (m.obj2 IS NOT NULL 
            AND m.obj2.count > 0) 
ORDER BY m.createDate DESC 
+0

好主意,但不幸的是似乎沒有工作。奇怪的是,這隻會返回第一個查詢的結果,而'ORDER BY'現在被忽略。如果我自己嘗試第二個查詢,它可以正常工作。是否有可能導致Hibernate在第一次查詢後退出? – aroth

+0

也許值得注意的是,'obj1'和'obj2'都引用相同的外部實體類型(所以它們引用同一個表中的不同行)。這可能導致問題嗎? – aroth

+0

我發現了一個可用的查詢的變體。但我仍然想知道爲什麼。詳情請看原文。 – aroth