2010-10-20 74 views
7

我有一個問題,我認爲應該很常見,但我找不到答案。hibernate @ManyToMany雙向渴望提取

我有2個對象:組和用戶。我的課是這個樣子:

class Group 
{ 
    @ManyToMany(fetch = FetchType.EAGER) 
    List<User> users; 
} 

class User 
{ 
    @ManyToMany(fetch = FetchType.EAGER) 
    List<Group> groups; 
} 

現在,當我嘗試從數據庫中獲取用戶它把它的所有組和所有組將其所有的用戶等。最後,我得到了一個stackoverflow例外。

我該如何解決這個問題,仍然有我的雙向關聯和到達列表中的對象的能力?

回答

8

如果您使用mappedBy屬性(您應該繼續使用)將您的雙向關聯的一側設爲關聯的擁有一側,您是否也遇到同樣的問題?就像這樣:

@Entity public class Group { 
    ... 
    @ManyToMany(fetch = FetchType.EAGER, mappedBy="groups") 
    List<User> users; 
} 

@Entity public class User { 
    ... 
    @ManyToMany(fetch = FetchType.EAGER) 
    List<Group> groups; 
} 

更新:我無法找到任何證據證明使用EAGER取上一個雙向關聯兩側,嚴禁轉載,據我所知,有Hibernate文檔中沒有這樣的限制,並提及/或JPA規範。

實際上,根據this comment從靈光伯納德一個(在某種程度上類似的)問題:

LAZYEAGER應該是正交的代碼庫無限循環問題。 Hibernate知道如何處理循環圖

對於我來說,上面是很清楚的,休眠應該能夠處理你的映射(正如我在評論中提到),我會受到誘惑而考慮任何矛盾的行爲作爲錯誤。

如果你可以提供一個測試用例,允許重現問題,我的建議是打開一個問題。

+0

是的。同樣的事情發生。我可以理解,這是有道理的b/c休眠需要爲每個列表帶來所有列表對象,並且它是一個無限循環。我的問題是,如果有可能限制休眠帶來的對象的深度(類似fetch_max_depth,但對於多對多)。 – refaelos 2010-10-21 12:49:16

+0

@Rafa實際上,我希望Hibernate能夠檢測週期並做適當的事情(但我沒有花時間來測試它)。另一方面,我不能說這種急切的加載多對多看起來是個好主意。 – 2010-10-21 13:02:49

0

當Hibernate嘗試熱切地獲取所需的所有內容時,Hibernate會正常工作。建模對象必須考慮休眠因此循環和堆棧溢出異常不會發生。

我做的是刪除關係的一方。您可以決定是否要刪除該邊或將其保留並將另一邊定義爲所有者。您還需要從該端刪除渴望的提取。

如果hibernate能夠提供一種機制來定義多對多關係中的抓取深度,那將會很不錯。

0

您可能希望將屬性「hibernate.max_fetch_depth」設置爲3,以限制提前獲取。