What is Hibernate Batch Processing?

In the previous article, we have discussed all the caching mechanisms in detail (you can check it here What is Hibernate Caching? ) In this article, we will discuss what is Batch Processing in Hibernate.

Sometimes, the situation arises when we want to insert the ‘n’ number of records in the table where n can be certainly a large value (n > 1000000). So, the possible solution can be we can take a for loop and iterate it over the Object like below:

Session session = factory.openSession();
Transaction tx = null;
tx = session.beginTransaction();
for(int i =0 ;i <= 1000000 ; i++){
Student student = new Student();
student.setNameOfStudent("ABC");
student.setAdd("A B Street");
session.persist(student);
}
tx.commit();
session.close();

Here, we are inserting such bulk data into the database. Hibernate will cache all the persisted objects using the second-level cache mechanism and due to which at a certain time it would throw OutOfMemoryException. So, in order to avoid this situation, we have a Batch processing Concept in Hibernate.

What is Batch Processing in Hibernate?

As we saw the above problem, while inserting a huge amount of records in the database at some point of the time it would throw OutOfMemoryException. 

  • Using the Batch Processing feature, we can create a batch_Size of size (20/50).
  • It will tell the Hibernate container that after some insert statement performs the flush of insert statement and release memory.
  • Hence, the exception will be avoided and data will be inserted.

This can be done in the following way:

int batch_size = 50;
Session session = factory.openSession();
Transaction tx = null;
tx = session.beginTransaction();
for(int i =0 ;i <= 1000000 ; i++){
Student student = new Student();
student.setNameOfStudent("ABC");
student.setAdd("A B Street");
session.persist(student);
if(i % batch_size == 0){
//flush a batch of inserts and release the memory
session.flush();
session.clear();
}
}
tx.commit();
session.close();
  • On line no. 1, we have set the Batch_size to 50
  • on line no. 10, we check that after every 50 insert rows it would flush the batch of insert and release memory.

Example of Batch Processing in Hibernate

In this example, we will create a Table and we will see the working of the Batch Processing.

Let us first create a configuration file hibernate.cfg.xml file. 

  • When we want to create a table Just write create like this- <property name=”hbm2ddl. auto”>create</property> and then replace it with update(otherwise it will give an error).
  • Add <property name=”hibernate.jdbc.batch_size”>50</property> to enable Batch processing with size 50.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/college</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password">khan</property>
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="hibernate.jdbc.batch_size">50</property>
    <property name="hibernate.show_sql">true</property>
    <property name="format_sql">true</property>
    <property name="hibernate.hbm2ddl.auto">update</property>



    <mapping class="com.batchprocessing.Student" />




  </session-factory>
</hibernate-configuration>

Now Create a java Class Student for setting and getting data. We are creating annotated-based classes so we won’t need a mapping file now. (for annotation you can see the previous article How to use Annotation in Hibernate?)

Student.java

In this class Just write the @Entity and @Table followed by table name.

package com.batchprocessing;

import javax.persistence.Cacheable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;



@Entity // specifies that class in an entity
@Table(name = "student") // defines the table
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
public class Student {

  @Id // indicate it is a primary key of the table.
  @GeneratedValue(strategy = GenerationType.IDENTITY) // annotation is to
                            // configure the way of
                            // increment of the
                            // specified
                            // column(field).
  @Column(name = "id")
  private int id;

  @Column(name = "name")
  private String nameOfStudent;

  @Column(name = "address")
  private String add;

  @Column(name = "collegename")
  private String cn;

  public int getId() {
    return id;
  }

  public void setId(int id) {
    this.id = id;
  }

  public String getNameOfStudent() {
    return nameOfStudent;
  }

  public void setNameOfStudent(String nameOfStudent) {
    this.nameOfStudent = nameOfStudent;
  }

  public String getAdd() {
    return add;
  }

  public void setAdd(String add) {
    this.add = add;
  }

  public String getCn() {
    return cn;
  }

  public void setCn(String cn) {
    this.cn = cn;
  }

  public Student() {
    super();
  }

  @Override
  public String toString() {
    return "Student [id=" + id + ", nameOfStudent=" + nameOfStudent + ", add=" + add + ", cn=" + cn + "]";
  }
}

Now, Create the main Test.java class

In this class, we will insert bulk data using the Batch processing feature.

package com.batchprocessing;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cache.ehcache.EhCacheRegionFactory;
import org.hibernate.cfg.Configuration;

/**
 * Hello world!
 *
 */
public class Test {
  public static void main(String[] args) {
    
    SessionFactory factory = new Configuration().configure().buildSessionFactory();
    int batch_size = 50;
    Session session = factory.openSession();
    Transaction tx = null;
    tx = session.beginTransaction();
    for(int i =0 ;i <= 1000000 ; i++){
      Student student = new Student();
      student.setNameOfStudent("ABC");
      student.setAdd("A B Street");
      session.persist(student);
      if(i % batch_size == 0){
        //flush a batch of inserts and release the memory
        session.flush();
        session.clear();
      }
    }
    tx.commit();
    session.close();
  }
}
  • on line no. 16, we configure the sessions.
  • on line no. 17, we took a variable batch_size with the value of 50.
  • on line no. 18-20, Session is open and the transaction begins using the beginTransaction() method.
  • on line no. 21 we have used a for loop to iterate over the object to persist in the database.
  • on line no. 26-29, we check that after every 50 insert rows it would flush the batch of insert and release memory.

Thus, this is How we use Batch processing in Hibernate which enhances the performance of your application. In the next article of this tutorial, we will discuss Hibernate Interceptors.