2011-08-29 31 views
2

我得到這個應用程序,它所做的是執行選擇,並在讀完後我不再需要該對象。休眠:讀取後刪除存儲在堆中的選定數據

因爲查詢是非常原子的,所以我沒有問題讀取數據。我的問題是那裏的數據量很大,因此最終在堆中存儲的舊對象導致內存不足異常。

我該如何執行選擇,擺脫以前的對象?

回答

0

的對象將由NH會話緩存被引用。要擺脫他們,你可以

  • 使用查詢後StatelessSession
  • Clear會話(這也從會話中刪除其他對象)
  • Evict每個對象
  • 的使用查詢不會加載實體,但根本不使用高速緩存的值或dtos(select a, bselect new Dto(a, b))。
+0

我相信我的整個問題是設計我對這個桌面應用程序(這似乎是自動的session-per-線程情況),StatelessSession看起來不錯 – javaNoober

0

不引用它們的對象將被垃圾收集,並且不會導致內存不足異常。所以,如果你確實得到這樣的異常,那麼對象仍然被引用,你需要找出它們是什麼。

如果錯誤是由過大的結果集引起的,則可以考慮通過setMaxResults()setFirstResult()Query.iterate()使用分頁。

+0

沒關係,這意味着在理論上,如果我有一個10點的對象,每1000個乙對象的集合,它應該收集對象1001的10倍? – javaNoober

+0

在每個對象中有10個對象和1000個B對象,您可能只需要增加堆大小。如果你有幾百萬個B對象上有幾百萬個A對象,那將會更棘手。在這種情況下,您可能需要遍歷列表或獲取頁面,例如1000個對象。您可能還需要驅逐您按照其他答案中的建議處理的對象。 'scroll'也是一件好事。 –

+0

是的,我有數百萬,只是懶與零,thx – javaNoober

0

在完成與您查詢的實體的工作後,您應該從會話緩存中將其逐出,然後將其解除引用,此時它將符合垃圾回收的條件。請參閱Hibernate指南中標題爲Managing the Caches的部分中的示例。這裏有一個例子:

ScrollableResult cats = sess.createQuery("from Cat as cat").scroll(); //a huge result set 
while (cats.next()) { 
    Cat cat = (Cat) cats.get(0); 
    doSomethingWithACat(cat); 
    sess.evict(cat); 
} 
+0

奇怪的事情,我創建我的entityManager一次,然後我在其他調用返回相同的EM。如果我得到一個會議指出的EntityManager的會話是空 – javaNoober

+0

如果您使用JPA 2.0,你應該叫EntityManager.detach(對象),而不是session.evict()。否則,調用EntityManager.getDelegate,將其轉換爲Session並使用evict。 –

+0

我會試着稍後分離。只是不明白,爲什麼我的(會議)getDelegate是空已經和MTA轉儲說的對象仍然存在 – javaNoober