How to enable batch inserts with Hibernate and Spring Boot
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
Hibernate can batch inserts, but it only does so when the configuration, identifier strategy, and persistence pattern all line up. In Spring Boot, enabling batching usually means setting Hibernate batch properties, inserting entities in groups, and avoiding features that force Hibernate to execute each insert immediately.
Turn on Hibernate batch settings
Start with the Hibernate properties in application.properties:
These settings tell Hibernate to group inserts into batches, reorder inserts for better batching opportunities, and optionally expose statistics so you can verify that batching is actually happening.
If you use MySQL, the JDBC driver may also need:
Without driver support, the ORM configuration alone may not produce the expected database-side batching behavior.
Insert entities in loops and flush periodically
Hibernate keeps managed entities in the persistence context, so large insert jobs should flush and clear periodically:
This pattern does two things:
- it gives Hibernate a chance to send the batched SQL
- it prevents the persistence context from growing without bound
For large imports, periodic flush() and clear() are often as important as the batch-size property itself.
Identifier strategy can disable real batching
One of the biggest Hibernate batching traps is GenerationType.IDENTITY. With identity columns, Hibernate often has to execute each insert immediately to retrieve the generated key, which prevents efficient batching.
If you want stronger batching behavior, sequence-based or pooled identifier strategies are usually better:
This is a major reason developers think batching is enabled when it is not actually happening.
saveAll() is not a guarantee by itself
Calling repository.saveAll(list) can be fine, but it does not automatically guarantee efficient batching. The underlying behavior still depends on:
- Hibernate batch settings
- transaction boundaries
- identifier strategy
- driver capabilities
So saveAll() is convenient, but the real work is done by the configuration and persistence context behavior underneath it.
Verify batching instead of assuming it
Do not assume batching works because the code looks batch-like. Check the logs, Hibernate statistics, or database monitoring.
If every insert still appears as a separate SQL round trip, look at:
- identity-based IDs
- driver flags
- missing transaction boundaries
- unexpected flushes triggered by other operations
Performance tuning is much easier once you confirm what the ORM is actually sending.
Keep transaction size realistic
Very large transactions can hold too much memory and too many locks. Very small transactions may prevent batching from helping enough. In practice, teams often batch in chunks such as 20, 50, or 100 entities and test with their actual database and schema.
There is no universal best batch size. Measure with real data.
Common Pitfalls
- Setting
hibernate.jdbc.batch_sizebut usingGenerationType.IDENTITY, which often defeats batching. - Forgetting driver-specific requirements such as MySQL's
rewriteBatchedStatements=true. - Inserting huge numbers of entities without periodic
flush()andclear(). - Assuming
saveAll()alone guarantees efficient JDBC batching. - Never verifying with logs or statistics whether batching is really happening.
Summary
- Enable Hibernate batching with the relevant Spring Boot Hibernate properties.
- Flush and clear the persistence context periodically during large insert jobs.
- Avoid identifier strategies that force Hibernate to execute inserts one by one.
- Check JDBC driver behavior, especially on MySQL.
- Verify batching with logs or statistics instead of assuming the configuration worked.
Related reading
- How to enable MySQL Query Log?
- How to enable pdo_mysql in the php docker image
- How to enable streaming replication in PostgreSQL running in kubernetes pods?
- How to ensure data consistency in Cassandra on different tables?
- How to enable native resolution for apps on iPhone 6 and 6 Plus?
- How to establish a consistent hash ring with 300 million virtual nodes within 10 seconds with C++
- How to enable Bearer authentication on Spring Boot application?
- How to enable CORS in Spring Boot - Not working

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.