2011-03-03 30 views
10

3.6.1.FinalHibernate的懶加載我使用的版本不工作

我在實體bean以下屬性

@JoinColumn(name = "FOLDER_PARENT_ID", referencedColumnName = "FOLDER_ID") 
@ManyToOne(cascade=CascadeType.MERGE, fetch= FetchType.LAZY) 
private FolderTbl parent; 

在我的單元測試,Assertnull失敗,因爲的getParent()是not null

assertNull(folderTbl.getParent()); 

我還需要做些什麼來阻止hibernate加載父項?

回答

8

即使您將lazy設置爲true,父項值也不會爲空。延遲加載使用代理對象並將其分配給父屬性。當我們嘗試使用父代(調用getParent())時,它將使用代理對象加載實際的父代對象。

如果您不想加載對象,請不要配置該項目的JPA屬性並將其設置爲瞬態。

+0

感謝您的解釋。我現在明白了 – 2011-03-03 12:19:13

6

父配置正確負載懶洋洋地,關鍵是你是錯誤測試它。

當你調用方法getParent()時,Hibernate會加載對象,當請求到實際的對象時它會加載。

您可以通過將show_sql設置爲true來檢查此事。它會在您調用時調用查詢getParent()

0

對於某些場景,您可能根本不需要加載懶惰集合。您可以使用下面的方法將會話從會話中分離出來。

public class. .... { 
..... 
    @JoinColumn(name = "FOLDER_PARENT_ID", referencedColumnName = "FOLDER_ID") 
    @ManyToOne(cascade=CascadeType.MERGE, fetch= FetchType.LAZY) 
    private FolderTbl parent; 
    ... 
    public void detachLazyObjects() { 
    parent = null; 
    } 

然後調用此方法將類從您需要的類中分離爲null。請謹慎使用此快捷方式,我建議您在採用此解決方案之前先考慮採用其他方法。

0

實際上,調用getParent()可能會返回一個代理實例,顯示您是否有一個父代。 如果您訪問id以外的字段,則會根據需要加載父項。

請注意,父項可能已被事務加載並因此駐留在第一級緩存中。如果是這樣,Hibernate通常不會對數據庫執行另一個查詢。

如前所述,如果您的實體對父對象有一個非暫時引用getParent()將始終返回一個非空值,即使父對象本身尚未加載。

0

Hibernate將Lazy抓取視爲提示。這裏是什麼JPA 2.0規範說在頁面364表9.

(可選)無論外地或財產 的價值應該被延遲加載或者必須預先抓取。 EAGER策略是對持久性提供者 運行時的要求,必須急切地提取該值。 LAZY策略是持久性提供者運行時的一個提示。