2011-08-14 51 views
-1

我使用Hibernate的命名查詢來執行存儲過程返回一個非常大的數據集(超過200萬行)DB是的Oracle 11gHibernate的存儲過程調用導致內存不足

例如: Query query = session.getNamedQuery(procName);

我從hibernate文檔中得知,不能像 http://docs.jboss.org/hibernate/core/3.3/reference/en/html/querysql.html中所述的那樣使用setFirstResult/setMaxResult。

一切都很好,在一個像100,000行的小數據集上。但是,只要我測試了1,000,000,就會發生OutOfMemory錯誤。

從查詢對象中,我得到一個listIterator。我假設數據只被提取一次,我迭代列表器(query.list().listIterator()

我沒有配置二級緩存。 在處理Oracle存儲過程時,這些設置是否會有所幫助?

query.setCacheMode(org.hibernate.CacheMode.IGNORE); query.setFetchSize(1000);
query.scroll(org.hibernate.ScrollMode.FORWARD_ONLY);

基本上,我如何管理使用存儲的特效在Hibernate中的大數據集檢索。

萬分感謝

+0

你爲什麼試圖返回200萬行?建議你分批處理。 –

回答

1

這完全取決於您如何處理查詢返回的數據。如果你把它當作一個典型的查詢 - 也就是調用它的list()並將結果存儲到一個集合中 - 那麼你會用很多行來消除你的內存限制。關鍵是要批量獲取和處理它們。我相信Hibernate這樣做的典型方式是將結果作爲ScrollableResults並定期記住flush()clear(),因爲它充當第一級緩存並將存儲所有正在加載的對象。在Hibernate中查看批處理的描述,但要小心不要混淆Hibernate的batch fetching及相關概念。他們是兩種不同的動物。

0

您的問題是少於Hibernate的一個內存使用情況。我有一個類似的情況,JMS消息在少量數據的情況下工作正常,然後所有東西都爆炸了。由於我懷疑你一次需要在內存中的所有2mm記錄,看看你是否可以使存儲過程更新以獲得限制和偏移量,以便它可以返回數據片而不是整個數據集。

相關問題