2011-01-24 36 views
4

使用hibernate標準時,只是更改連接類型會影響根域類的子集合的結果。在條件中使用左連接時的Hibernate Child Collection Limited

例如,具有一流的家長有一個一對多的關係,帶班的孩子與下列數據:

 
Parent 
| id | Name  | 
| 1 | Parent 1 | 

Child 
| id | parent_id | Name | 
| 1 |   1 | Child1 | 
| 2 |   1 | Child2 | 

使用下面的休眠條件返回1個父行和訪問子集合結果在兩行返回:

session.createCriteria(Parent.class) 
    .createCriteria('child', CriteriaSpecification.INNER_JOIN) 
    .add(Restrictions.eq('name', 'Child1')) 
    .list() 

但是,用左改變上面的代碼加入時,則返回1個父行,但在訪問子集時,只返回匹配的子行。

session.createCriteria(Parent.class) 
    .createCriteria('child', CriteriaSpecification.LEFT_JOIN) 
    .add(Restrictions.eq('name', 'Child1')) 
    .list() 

爲什麼會出現這種副作用?根據您的預期結果,我發現了一些關於使用或避免這種副作用的討論,但沒有說明爲什麼首先出現這種副作用以及它是否是有意的。最接近的直接問題是陳舊的缺陷(http://opensource.atlassian.com/projects/hibernate/browse/HHH-3872)。

  • 編輯器3/24:固定數據*
+1

伴侶,我所有的知識告訴我,內部連接應該取剛一行。我想你在這裏發生了一些事情。我將收藏這本書,以便跟隨我所缺失的內容。如果是我,我會非常感激你。 – 2011-03-19 20:10:06

回答

0

我已經試過了這一點:執行這個查詢,之後得到調用parent.getChildren(當 ),則:

  • LEFT JOIN:執行一個包含父項和一個匹配子項的查詢,調用getChildren()時不執行後續查詢
  • INNER_JOIN:執行2個查詢:一個查找父項調用的getChildren()時

如此看來,LEFT_JOIN孩子打電話時(在這種情況下,匹配子女)急切地取出並已填充的家長的孩子收集孩子的匹配,另一個。 但是,對於INNER_JOIN,這個集合被標記爲代理並在調用getChildren()時被初始化;這第二個查詢當然不再考慮名稱的限制,只會爲父提取所有子代。

這似乎發生在hibernate內部,這意味着連接類型將影響hibernate如何處理結果。儘管左連接和內連接之間生成的SQL略有不同(在我的測試中,parent.id和child.id在select子句中是兩次),但在DB瀏覽器中運行SQL時返回的結果是相同的。

我沒有足夠的經驗來確定這是否是一個錯誤,但它不像一個。