2013-04-30 192 views
0

我有一個JPA設置,如果我不使用延遲加載,幾乎整個數據庫將被加載。我也直接在模型上使用序列化,所以有時我需要初始化代理。JPA Hibernate集合不是懶惰加載

我只想對集合使用延遲加載。事實上,一些奇異的實體被熱切地提取工作得很好。但是無論我如何設置集合,我都從未獲得代理集合,我總是得到完全加載的集合。

這是一些示例代碼:

@Entity 
public class Thread implements Externalizable { 
    @OneToMany(mappedBy = "parentThread", fetch = FetchType.LAZY) 
    public List<Reply> getReplies() { 
     return replies; 
    } 

所以這裏的問題是,當我檢查調試程序,答覆的persistantBag列表總是充滿了信息,並在實際的回覆對象空的代理,而不是我想要的。

我使用entityManager.find(Thread.class,「ID」)當我想要線程和像這樣的所有集合總是完全加載,無論我有fetch = FetchType.LAZY或不。

據我所知,設置fetchtype懶惰應該工作,因爲我想要它。另外,我希望在使用thread.getReplies()時加載實體,以便序列化並將它們發送到客戶端。我不知道getReplies是否可以與代理實體一起工作,因爲我從來沒有收集到任何延遲加載的集合。

另一方面,我不使用Intellij,並用它來設置與Hibernate JPA。 我也問過一個類似的問題,我希望集合是完全空的,但我不確定這是否可能,而我爲此而提出這個問題。

JPA Hibernate want lazy load to return empty collection

我還沒有看到關於計算器這個看似基本的問題一個很好的答案。如果問題真的以教學方式回答,請僅回覆一個鏈接,因爲我是JPA/Hibernate和真正的數據庫的新手。

非常感謝您提前!

回答

2

懶惰集合不包含代理。該集合本身是一個延遲加載的集合。這意味着當你從數據庫中獲得一個線程時,它的回覆列表將不會被初始化。

調用getReplies()將簡單地返回這個未初始化的列表。只有當調用列表本身的方法(如size()iterator())時,Hibernate纔會通過執行加載線程所有回覆狀態的SQL查詢來初始化列表。

使用調試器來檢查集合包含的內容不是一個好主意,因爲調試器通常會調用列表背後的列表中的方法,這會導致列表自行初始化。您可以使用Hibernate.isInitialized(thread.getReplies())方法檢查集合是否已初始化。

關於您的其他問題:Hibernate用於將數據庫行映射到對象。如果一個線程有回覆,Hibernate永遠不會通過返回一個空列表來告訴你它沒有任何迴應。這將是一個嚴重的錯誤。如果您不想加載回覆,則不要在回覆列表中調用任何方法。

+0

謝謝!抱歉忘記接受你的答案=) 我錯過了調試器實際上調用了背後的方法,這引起了我的困惑。 – 2015-07-28 11:03:02