2010-06-18 113 views

回答

3

Hibernate Docs這個片段限定符意味着你可以重寫懶惰與渴望,而不是周圍的其他方式:

如果你使用屬性級別的懶惰 取(用字節碼 儀器) ,有可能 強制Hibernate立即使用獲取所有 屬性來獲取第一個查詢 中的惰性 屬性。

不同尋常的是,如果您使用Criteria API從急於變爲懶惰,看起來可以。只需在相關聯接中調用setFetchMode(FetchMode.LAZY)即可。

+1

它看起來像setFetchMode(FetchMode.LAZY)仍然有點熱切地提取它們(即,它們不是由急切的連接提取,而是由n + 1在最初的SQL查詢之後選擇)。似乎沒有辦法完全覆蓋EAGER設置。 – jsight 2010-11-05 18:33:53

+0

我有同樣的經歷。此註釋的JavaDoc似乎存在爭議(http://opensource.atlassian.com/projects/hibernate/browse/HHH-980),但無論使用SELECT還是LAZY,孩子仍然會抓取EAGER。不知道我是否做錯了什麼,或者是否存在Hibernate錯誤。 – atrain 2011-05-13 15:09:19

+0

'FetchMode.LAZY'也被棄用 – 2011-08-30 10:22:37

4

我有一種情況,由於歷史原因,在幾個一對多的依賴關係之間進行了熱切的獲取。多年來很多地方都依賴它,所以很難關閉。然而在某些情況下,渴望獲取會阻礙:對於表中的每一個更大的選擇,它都會爲每個對象的每個集合產生100個小型子查詢。我找到了解決這個問題的方法,並不是真的重寫了渴望的獲取,而是對我來說同樣有用:只需創建一個能夠一次執行所有子讀取的單個查詢。這將對數據庫進行1次物理查詢,而不是使用hibernate遍歷依賴關係圖併產生100個查詢。

所以我代替

Query q = session.createQuery("from Customer c"); 

通過

Query q = session.createQuery("from Customer c " + 
           "left join fetch c.vats v " + 
           "left join fetch v.klMemos bk " + 
           "left join fetch bk.ferryKlMemos"); 

1客戶有很多的增值稅號,1增值稅號碼有許多klmemos等。舊的情況將首先取消客戶,然後hibernate將開始逐個取回每個依賴集合。第二種形式會將所有內容加載到一個本地查詢中,並且hibernate將查找它填充對象緩存中的渴望集合所需的全部內容。

注意這種方法還可以模擬配置爲懶惰的集合的快速提取獲取,因爲您正在以熱切(高效)的方式填充所有「懶惰」集合。