2011-10-07 37 views
1

我有一個批處理過程,它可以逐個保存1000000條記錄。每個記錄都有它自己的子表。我使用Spring 2.5.6,Hibernate和JPA來做到這一點。但是一小時後它就會失去記憶。任何人都可以建議我在應用程序中出現什麼問題?批處理在Spring + Hibernate + JPA中跳出內存

下面是代碼:

Public void processFeeds(List<Objects> feeds){ 

     for(Feed feed : feeds){ 
     Feed feed=getDAOMainFeedService().persist(feed); 

     //Saving the child information 
     if(feed.getID()>0) { 
      for(Address address : feeds.getAddress()){ 
       getDAOAddressService().persist(feed.getID,address); 
     } 

     for(PersonalInfo pi: feeds.getPersonalInfo){ 
       getDAOPIService().persist(feed.getID,pi); 
     } 
    } 
} 

} 

//service Class code: 
public class MainFeedServiceDAOImpl extends JpaDaoSupport implements IVehYmmRevDAO 
public Feed persist(Feed feed) 
    { 


     try 
     { 
      getJpaTemplate().persist(feed); 
      feed=getJpaTemplate().merge(feed); 
      getJpaTemplate().flush(); 

      return feed; 
     } 
     catch (Exception exception) 
     { 
      logger.error("Persit failed", 
        exception); 
      throw new DatabaseServiceException(
        "Persit failed", exception); 
     } 
    } 

} 

其他DAO類也具有相同的MainFeedServiceDAOImpl實現,它使用的是Spring到數據庫服務層注入的上方。請提出一些建議。

+0

詹姆斯DW的回答下面是非常對你的問題。然而,我的reccomandation是爲了批處理作業休眠(或任何其他ORM),即使你解決了你的內存問題,你仍然會遇到其他問題。只需使用JDBC。 –

回答

4

您的程序運行內存不足的原因是因爲您插入的每個對象都保留在會話中。你需要偶爾清除它。

我會改變這樣的堅持方法:

public void persist(List<Feed> feeds) 
{ 
    int count = 0; 
    try 
    { 
     for (Feed feed : feeds) { 
      getJpaTemplate().persist(feed); 
      if (count % 10000 == 0) { 
       getJpaTemplate().flush(); 
       getJpaTemplate().getEntityManager().clear(); 
      } 
      count++; 
     }    
    } 
    catch (Exception exception) 
    { 
     logger.error("Persist failed", exception); 
     throw new DatabaseServiceException("Persist failed", exception); 
    } 
} 

http://docs.jboss.org/hibernate/core/3.3/reference/en/html/batch.html#batch-inserts

您可以按照您的地址和個人信息的對象相同的模式,但如果你有正確的映射和級聯設置你可能不需要那麼做。

+0

在我看來,10000會更好。否則投票 – MarianP

0

雖然批量調用來堅持feed會有所幫助,但這隻會延遲OOME的發生。當系統需要處理更多數量的提要時,它會在OOME進入持續階段之前遇到OOME。批處理邏輯還應該添加到要保留的提要的位置,然後輸入到系統中,這樣您就可以知道在任何時間點存儲在內存中的對象的最大數量。