Пакетный процесс не хватает памяти в Spring + Hibernate + JPA - PullRequest
1 голос
/ 07 октября 2011

У меня есть пакетный процесс, который сохраняет 1000000 записей по одной. Каждая запись имеет свои дочерние таблицы. Я использую Spring 2.5.6, 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 в слой службы базы данных выше. Пожалуйста, дайте несколько предложений.

Ответы [ 2 ]

4 голосов
/ 07 октября 2011

Причина, по которой вашей программе не хватает памяти, заключается в том, что каждый вставляемый вами объект остается в вашем сеансе. Вы должны очистить это время от времени.

Я бы изменил постоянный метод следующим образом:

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 голосов
/ 06 августа 2012

Хотя пакетирование вызовов для сохранения каналов могло бы помочь, это только задержит возникновение OOME.В тот день, когда вашей системе потребуется обработать большее количество фидов, она перейдет в OOME, прежде чем она перейдет на постоянную стадию.Логика пакетирования также должна быть добавлена ​​в том месте, где каналы сохраняются, входят в вашу систему, чтобы вы знали максимальное количество объектов, присутствующих в памяти в любой момент времени.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...