2010-11-09 29 views
1

我正在使用hibernate的批量提取來提高查詢性能。在我的persistence.xml我已經添加了以下設置:休眠:批量提取的意外獲取順序

<property name="hibernate.default_batch_fetch_size" value="50"/> 

我有一個實體A,其中有一個1:N關係的實體B.此關係的數據是獲取懶洋洋地。現在,我已經得到了以下情況:

  • 我負載類型中的10000個實體從DB
  • 我遍歷這些實體,並通過調用初始化a.getBs懶惰的關係()大小()
  • 這樣做時,hibernate不僅會初始化當前實體的依賴關係,還會從列表中加載49個附加實體的依賴關係。這種行爲是預期的。

生成的SQL類似於這樣:

select 
    b0_.SOMETHING as SOMETHING1_1_, 
    ... 
from 
    XYZ.B b0_ 
where 
    b0_.A_ID in (
     ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ... 
    ) 

我真正的問題是,Hibernate是不加載結果列表中的實體按預期的順序。當我從列表中訪問第一個條目時,它不會加載實體2-50的數據,但會從列表中加載49個隨機條目的數據。 (例如,它可以初始化實體3,7,100,2001 ...的數據)。這種行爲很奇怪,我想知道如何改變它以預期的順序加載數據。

當前存在的問題,與所描述的行爲有關。

  • 內存使用情況。在迭代列表時,hibernate正在初始化大量數據,這將在稍後需要。除了上面的算法外,我還添加了一些代碼,它從列表中刪除處理過的記錄並調用session.evict(entity),使實體符合垃圾回收的條件。這當然不是現在。
  • 迭代開始時,查詢速度非常慢,因爲hibernate正在查詢幾乎每個處理實體的數據庫。這會導致問題,因爲我正在將實體寫入Web應用程序的流中,以便在處理時進行下載。結果,下載速度在開始時非常緩慢,並且在更多實體加載到內存並且需要更少的數據庫調用時加速。

非常感謝您的幫助和問候

托馬斯

+0

你在使用列表iterator()嗎? – KarlP 2010-11-09 16:57:44

+0

我測試了迭代器和新的for循環(for(A a:resultlist)) – Thomas 2010-11-10 12:48:39

回答

2

當你說的Hibernate沒有按預期的順序加載實體,你告訴它預期的順序是什麼?也就是說,B的映射是否包含order-by屬性?如果沒有,那麼他們 Hibernate數據模型中沒有順序,並可以以任何順序(可能是數據庫默認值)加載。

否則,我的理解是,Hibernate應該在查找要加載的pkeys時應用順序約束。因此,可能值得在郵件列表中將它作爲潛在的錯誤。