Batch inserts and bulk updates

Hibernate · lesson 23 of 32 · 4 min read

Turn fifty round trips into one, and know what a bulk statement does to the context.

Open this lesson in the learning hub

Key points

  • Set hibernate.jdbc.batch_size (30-50 is typical). Without it every INSERT is its own round trip, however tight your loop is.
  • Batching needs ids up front, so IDENTITY silently disables it. Use a SEQUENCE with a matching allocationSize.
  • Add order_inserts and order_updates so Hibernate groups statements by table instead of breaking every batch.
  • In a long loop, flush() then clear() every batch, or the context holds every entity until the heap runs out.
  • A JPQL update or delete is one statement, but it bypasses the context: no cascades, no callbacks.
  • Call em.clear() after a bulk statement, or the next find() returns the stale object from the first level cache.

Example

# --- application.properties -------------------------------------
spring.jpa.properties.hibernate.jdbc.batch_size=50
spring.jpa.properties.hibernate.order_inserts=true
spring.jpa.properties.hibernate.order_updates=true
# ids must not come from IDENTITY, or batching is off whatever you set

# --- the loop ----------------------------------------------------
# @Transactional
# public void importAll(List<Book> books) {
#     for (int i = 0; i < books.size(); i++) {
#         em.persist(books.get(i));
#         if (i % 50 == 0) {        // one batch out, one context emptied
#             em.flush();
#             em.clear();
#         }
#     }
# }

# --- one statement instead of N ----------------------------------
# int rows = em.createQuery("update Book b set b.archived = true where b.publishedOn < :cut")
#              .setParameter("cut", cutoff)
#              .executeUpdate();
# em.clear();                        // loaded Books are now stale

Batch size plus a sequence turns an import from minutes into seconds.

This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Hibernate course, and every lesson in it is listed on the Hibernate contents page.