Hibernate Batch Processing

When we are working on an application which deals with Database for data, we may need to do bulk insert, update to be done. In hibernate with basic approach we can do the same as:

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
for ( int i=0; i<10000; i++ ) {
    Employee emp = new Employee(.....);
    session.save(emp);
}
tx.commit();
session.close();

This approach can lead to OutOfMemoryException because Hibernate caches all the newly inserted Employee instances in the session-level cache.

Batch inserts:

We can follow the below approach:

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
   
for ( int i=0; i<10000; i++ ) {
    Employee emp = new Employee(.....);
    session.save(emp);
    if ( i % 50 == 0 ) { //50, same as the JDBC batch size
        //flush a batch of inserts and release memory:
        session.flush();
        session.clear();
    }
}
tx.commit();
session.close();

Batch Updates:

We can follow below mentioned approach:

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
   
ScrollableResults emps = session.getNamedQuery("GetEmployees")
    .setCacheMode(CacheMode.IGNORE)
    .scroll(ScrollMode.FORWARD_ONLY);
int count=0;
while ( emps.next() ) {
    Employee emp = (Employee) emps.get(0);
    emp.updateXXX(...);
    if ( ++count % 20 == 0 ) {
        //flush a batch of updates and release memory:
        session.flush();
        session.clear();
    }
}
tx.commit();
session.close();

StatelessSession interface:

It is one of the alternative to the above mentioned approache where we create statelesssession which has no persistent context associated with it. Stateless session does not implement a first-level cache nor interact with any second-level or query cache. Operations performed using a stateless session never cascade to associated instances. Collections are ignored by a stateless session.

StatelessSession session = sessionFactory.openStatelessSession();
Transaction tx = session.beginTransaction();
   
ScrollableResults emps = session.getNamedQuery("GetEmployees")
    .scroll(ScrollMode.FORWARD_ONLY);
while ( emps.next() ) {
    Employee emp = (Customer) emps.get(0);
    emp.updateXXX(...);
    session.update(emp);
}
   
tx.commit();
session.close();

The insert(), update() and delete() operations defined by the StatelessSession interface are considered to be direct database row-level operations. They result in the immediate execution of a SQL INSERT, UPDATE or DELETE respectively.