Учитывая информацию из вопроса и комментариев, это то, что происходит в вашем коде:
- Для каждой записи, которую нужно вставить, вы делаете выбор с помощью критериев.
- Сделайте проверку и, в зависимости от ситуации, вы сохраните или объедините запись.
Вы должны понимать, как сеансы гибернации ведут себя в некоторых ситуациях. Когда вы выполняете операцию в режиме гибернации, то, что вы делаете (в первый момент), обновляет сеанс гибернации. При вставке, удалении или обновлении операция будет выполняться в сеансе, Hibernate даже будет записывать инструкцию SQL, но она не будет немедленно сброшена в вашу БД (да, это вводит в заблуждение) .
Обычно все сбрасывается и завершается транзакция, но в определенных ситуациях hibernate будет сбрасывать операции, чтобы поддерживать сеанс в актуальном состоянии. В вашем случае у вас есть несколько записей для вставки / объединения, но перед каждой операцией вы выполняете выбор. Hibernate обнаруживает эту операцию и сбрасывает каждую ранее сохраненную операцию просто потому, что не имеет смысла запрашивать БД, если есть ожидающие операции, которые необходимо очистить. БД должна быть в самом актуальном состоянии, которое возможно. Не пытайтесь бороться с этим, он предназначен для такой работы.
Так что я думаю, что когда ваш выбор занимает слишком много времени, это происходит потому, что hibernate сбрасывает предыдущую операцию вставки / обновления .
Как это решить:
Я не могу придумать никакого простого способа решить эту проблему. Вам придется пересмотреть свой подход.
Есть одна важная вещь: даже если бы вам нужно было только чистые вставки без какой-либо проверки, у вас были бы некоторые проблемы, потому что ваш код пытается вставить тысячи записей. Большая проблема в том, что, как я писал ранее, hibernate не сбрасывает операции до конца транзакции. Таким образом, он будет хранить в памяти все выполняемые операторы. Есть большая вероятность того, что вам не хватит памяти.
Первое, что я хотел бы сделать, это проверить документы гибернации при пакетной обработке (начните с документов ). После этого я бы разработал стратегию для оптимизации необходимости добавления большого количества записей и необходимой проверки.
Вместо того, чтобы работать с отдельными записями, работайте с кусками данных.
Из небольшой доступной информации я бы попробовал этот рабочий процесс:
Прежде всего, определите свойство размера партии для режима гибернации (опять же, проверьте документы при дозировании)
- При обработке ваших данных возьмите кусочек данных с тем же размером, который определен для размера пакета
- Сделайте выбор, который выбирает каждую возможную запись для проверки в тех записях, которые должны быть вставлены
- Выполните необходимые проверки, чтобы проверить, является ли это слияние или вставка для каждой записи в срезе
- Группирует вставки, объединяет и выполняет операции. Промывка и очистка спящего режима
- Возьмите следующий фрагмент данных и повторите процесс
По сути, это «та же» процедура, которую вы выполняете, но она будет выполняться для кусков записей вместо того, чтобы делать это в каждой отдельной записи.