Есть ли опыт использования Hibernate batch update?
Что проверяют
Работали ли вы с массовыми операциями через Hibernate на практике и знаете ли, почему «просто поставить batch_size» часто ничего не меняет. Следом обычно спрашивают, как вы убедились, что пакетная отправка реально работает, и как у вас генерировались ключи.
Как отвечать
Опирайтесь на свой случай: что за задача (импорт, пересчёт статусов, миграция данных), сколько строк, сколько длилось до и после. Цифры должны быть ваши. Технический каркас:
- включение:
hibernate.jdbc.batch_size, в Spring Boot черезspring.jpa.properties.hibernate.jdbc.batch_size. По умолчанию пакетная отправка выключена; - порядок:
hibernate.order_insertsиhibernate.order_updatesгруппируют операции по сущностям, иначе вперемешку идущие вставки дробят пакеты; - генерация id: при
GenerationType.IDENTITYвставки не пакетируются, Hibernate нужен id сразу. НуженSEQUENCEсallocationSizeбольше единицы; - память: каждые N записей
flush()иclear(), иначе контекст персистентности разрастается и тормозит dirty checking. Условиеi % batchSize == 0срабатывает уже на первой записи, правильно(i + 1) % batchSize == 0; - драйвер:
reWriteBatchedInserts=trueдля PostgreSQL,rewriteBatchedStatements=trueдля MySQL, тогда пакет превращается в многострочный запрос; - альтернативы: если все строки меняются одинаково, быстрее один
UPDATE ... WHEREчерезexecuteUpdate()илиStatelessSession. Но они идут мимо контекста, кеша второго уровня и колбэков.
Проверяйте результат через hibernate.generate_statistics, datasource-proxy или лог базы. В Hibernate 6 вместо устаревшего save() используйте persist().
Если опыта не было, скажите прямо и объясните, что проверили бы первым делом: стратегию id и фактическое число запросов.
Где спотыкаются
Ставят batch_size, оставляют IDENTITY и уверены, что вставки идут пачками.
Забывают clear() на сотнях тысяч сущностей и получают OutOfMemoryError или долгий flush.
Путают batch update с bulk update: говорят про пакеты JDBC, а описывают один JPQL-запрос на всю таблицу.