Hibernate вызывает исключение нехватки памяти при сохранении большого количества объектов - PullRequest
1 голос
/ 26 мая 2011

В моем приложении я использую CSVReader & Hibernate для импорта большого количества объектов (например, 1 500 000 или более) в базу данных из файла CSV. Код выглядит так:

        Session session = headerdao.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();

        int count = 0;
        String[] nextLine;

        while ((nextLine = reader.readNext()) != null) {
            try {

                if (nextLine.length == 23
                        && Integer.parseInt(nextLine[0]) > lastIdInDB) {
                    JournalHeader current = parseJournalHeader(nextLine);
                    current.setChain(chain);
                    session.save(current);
                    count++;
                    if (count % 100 == 0) {
                        session.flush();
                        tx.commit();
                        session.clear();
                        tx.begin();
                    }
                    if (count % 10000 == 0) {
                        LOG.info(count);
                    }

                }

            } catch (NumberFormatException e) {
                e.printStackTrace();
            } catch (ParseException e) {
                e.printStackTrace();
            }

        }
        tx.commit();
        session.close();

При наличии достаточно больших файлов (где-то около 700 000 строк) я получаю исключение из памяти (пространство кучи).

Кажется, что проблема как-то связана с гибернацией, потому что, если я прокомментирую только строку session.save (current); работает нормально. Если он не прокомментирован, диспетчер задач показывает постоянно увеличивающееся использование памяти javaw, а затем в какой-то момент анализ становится очень медленным и происходит сбой.

parseJournalHeader() не делает ничего особенного, он просто анализирует сущность на основе String[], которую дает читатель csv.

1 Ответ

1 голос
/ 26 мая 2011

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

Попробуйте вместо этого использовать StatelessSession.

...