Saving 10,000 entities with `saveAll` takes minutes. How do you make inserts fast?
basicBy default each insert is a separate statement and round trip. Enable JDBC batching so Hibernate groups statements into one executeBatch call, and flush/clear the persistence context periodically.
spring:
jpa:
properties:
hibernate:
jdbc.batch_size: 50
order_inserts: true
order_updates: true
batch_versioned_data: truefor (int i = 0; i < items.size(); i++) {
em.persist(items.get(i));
if (i % 50 == 49) { em.flush(); em.clear(); } // bound memory, send the batch
}- PostgreSQL JDBC additionally needs
reWriteBatchedInserts=trueto turn batches into multi-row inserts; MySQL Connector/J needsrewriteBatchedStatements=true. order_insertsgroups by entity type so interleaved parent/child inserts still batch.- Without
clear()the persistence context grows and dirty checking slows down (O(n) per flush).
- Does batching work with
GenerationType.IDENTITY? No, Hibernate must execute each insert immediately to get the id, so JDBC batching is disabled for that entity. - Does
saveAllitself batch? It just loopspersist; batching is a Hibernate/JDBC setting.