Search code examples
hibernatejpaspring-data-jpabatch-processingupdates

Batch update with Spring data jpa


I am trying to update a table in batch. Below is my configuration:

spring.jpa.properties.org.hibernate.flushMode=COMMIT
spring.jpa.properties.hibernate.jdbc.batch_size=10
spring.jpa.properties.hibernate.order_inserts=true 
spring.jpa.properties.hibernate.order_updates=true
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.org.hibernate.SQL=DEBUG
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.generate_statistics=true
spring.jpa.properties.hibernate.jdbc.batch_versioned_data=true

Below are the methods where the actually :

    @Transactional(propagation=Propagation.REQUIRES_NEW)
public void updateEmployeeDetails(Map<String, List<String>> orgEAMap) {
    ....
    updateEmployee(employeeMap);
}


public void updateEmployee(Map<String, String> employeeMap) {
    //int i =0;
    for (Entry<String, String> mapEntry : employeeMap.entrySet()) {
        Query query = em.createNativeQuery("UPDATE employee emp SET emp.name = :name WHERE emp.id = :id");
        query.setParameter("id", mapEntry.getValue());
        query.setParameter("name", mapEntry.getKey());
        query.executeUpdate();
        //if(i==10){
            //LOG.info("Flushmode"+em.getFlushMode());
            //em.flush();
        //}
        //i++;
    }
}

I tried flushing after a certain count manually but the flush(partial-flush) is already happening after each query execution. From the statistics logs,i can see that there are 10 statement being created and 0 batch and flush is happening.


Solution

  • The batch configuration of Hibernate affects just how entities and their changes get handled. Explicit queries get executed immediately.

    If you want to utilize batch processing, I see two options:

    1. Actually load the entities, change the attribute you want to update, and let Hibernate do its thing. Of course, this creates the additional overhead of loading entities which is probably not desired.
    2. Use SQL directly using the datasource, side stepping the EntityManager. I'd recommend using Spring Template for this.

    Note: you might want to update the version attribute as well to avoid lost updates.