Hibernate по умолчанию не включает пакетирование. Это означает, что он будет отправлять отдельный оператор SQL для каждой вставки.
Чтобы вставить такой массив данных за один раз, вы должны использовать пакетную вставку. Вот свойства гибернации: hibernate.jdbc.batch_size = 50
и hibernate.order_inserts = true
Первое свойство указывает Hibernate собирать вставки в пакетах по 50 (50 используется здесь только в качестве примера ..). Свойство order_inserts говорит Hibernate о том, что нужно потратить время на группировку вставок по сущности, создавая большие партии.
Затем вы должны выбрать явную или неявную очистку.
- Implicit: просто установить пакет Свойство size и hibernate сделают все остальное.
- Явное
flush
и clear
for (int i = 0; i < 10; i++) {
if (i > 0 && i % BATCH_SIZE == 0) {
entityManager.flush();
entityManager.clear();
}
A a = new A();
entityManager.persist(a);
}
Так зачем использовать второй вариант?
Когда мы сохраняем объект, Hibernate сохраняет его в контексте постоянства. Например, если мы сохраняем 2000 сущностей в одной транзакции, у нас останется 2000 экземпляров сущностей в памяти, что может вызвать OutOfMemory ...
Другая проблема ... как вы сказали, что используете MySQL. Пакетный режим гибернации не работает с IdGenerator IDENTITY
, поэтому нельзя использовать пакетную вставку с функцией AUTO-INCREMENT
mysql. Поскольку генерация последовательности не существует в MySQL, вы застряли с генератором TABLE
. Но генератор таблиц менее производительный, чем личность. Чтобы упомянуть Влада Михалча (цитата из его знаменитой книги High Performance Java Persistence
)
При использовании MySQL и необходимости в большом количестве вставок Для этого стоит использовать JOOQ framework.