Saturday 20 August 2016

Batch Processing Example in Hibernate

This post explain batch processing in hibernate.Before moving to the example itself ,it would be better to understand what is batch processing and why this concept comes into the scenario.
Batch processing in hibernate or related to database is performing collection  of database transactions.
API required for batch processing is nothing different from general Hibernate related api, but when there is a requirement of performing insert,update on a large number of record like 1000000.In such scenario the batch processing would not work normally ,it throws OutOfMemoryException.
         Actually when we perform session.save(obj)  or session.update(obj) or session.saveUpdate(obj) the value not saved to database until the commit() get executed,it persist in the hibernate session level cache . The hibernate session level cache stored in JVM hence after persisting the allowed size of data in JVM it throws  OutOfMemoryException. To avoid this problem we flush the cache after performing any of session.save(obj)  or session.update(obj) or session.saveUpdate(obj) .

The below given example is of batch processing in Hibernate-
In this example i am taking a real life scenario like online Order for a product on product launch day.
This is just an example taken for explaining the batch processing.

Code Block
-----------------------------------------------------------------------------------------
Session session = SessionFactory.openSession();
Transaction tx = session.beginTransaction();
for ( int i=0; i<1000000; i++ )
{
    Order order= new Order("o"+i,String.valueOf(i),new Date());
    session.save(order);
    if( i % 50 == 0 )
    {
        session.flush();//flush after a batch insertion and release memory:
        session.clear();
    }
}
tx.commit();
session.close();
----------------------------------------------------------------------------------------

ORM /Entity Calss
package com.nik.hibernate.pojo;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;
@Entity
@Table(name="ORDER")
public class Order implements Serializable {

private static final long serialVersionUID = -2955407588841152439L;

@Id
@Column(name="order_id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private String orderID;
@Column(name="customer_id")
private String customerId;
@Column(name="order_date")
private Date orderDate;
                     Order(String orderId,String customerID,Date orderDate){
                            this.orderId=orderId;
                            this.customerID=customerID;
                            this.orderDate=orderDate;
                     }
                     public String getOrderID() {
return orderID;
}
public void setOrderID(String orderID) {
this.orderID = orderID;
}
public String getCustomerId() {
return customerId;
}
public void setCustomerId(String customerId) {
this.customerId = customerId;
}
public Date getOrderDate() {
return orderDate;
}
public void setOrderDate(DateorderDate) {
this.orderDate = orderDate;
}
}


hibernate.cfg.xml

<?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="connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password">toor</property>
    <property name="show_sql">true</property>
    <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="hibernate.hbm2ddl.auto">update</property>
    <property name="hibernate.jdbc.batch_size"> 50 </property>
      </session-factory>

</hibernate-configuration>

-----------------------------------------------------------------------------------------------------



Saturday 27 December 2014

Hibernate Second Level cache Demonstration


 Here we demonstrate the second level cache of hibernate using ehcache.Here in this example we are using one entity student and READ_ONLY cache strategy to handle cache.


 StudentInfo.java

package com.nik.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

@Entity
@Table(name = "student")
@Cache(usage=CacheConcurrencyStrategy.READ_ONLY,region="studentCache")

public class StudentInfo implements java.io.Serializable {
   @Id
   @GeneratedValue
   @Column(name = "student_id")
    private long studentId;

   @Column(name = "student_name")
    private String studentName;

    public StudentInfo() {
    }

    public StudentInfo(String studentName) {
        this.studentName = studentName;
    }

    public long getStudentId() {
        return this.studentId;
    }

    public void setStudentId(long studentId) {
        this.studentId = studentId;
    }

    public String getStudentName() {
        return this.studentName;
    }

    public void setStudentName(String studentName) {
        this.studentName = studentName;
    }

}

Hibernate configuration file is as follows:

hibenate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
                                         "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
 <session-factory name="">
  <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
  <property name="hibernate.connection.url">jdbc:mysql://localhost/testdb</property>
  <property name="hibernate.connection.username">root</property>
  <property name="connection.password">*********</property>
  <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
  <property name="hibernate.show_sql">true</property>
  <property name="hbm2ddl.auto">create</property>
<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
              
         <!-- enable second level cache and query cache -->
         <property name="hibernate.cache.use_second_level_cache">true</property>
         <property name="hibernate.cache.use_query_cache">true</property>
          <property name="net.sf.ehcache.configurationResourceName">/ehcache.xml</property>
  <mapping class="com.nik.model.StudentInfo" />
   
 </session-factory>
</hibernate-configuration>



ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true"
    monitoring="autodetect" dynamicConfig="true">

    <diskStore path="java.io.tmpdir/ehcache" />

    <defaultCache maxEntriesLocalHeap="10000" eternal="false"
        timeToIdleSeconds="120" timeToLiveSeconds="120" diskSpoolBufferSizeMB="30"
        maxEntriesLocalDisk="10000000" diskExpiryThreadIntervalSeconds="120"
        memoryStoreEvictionPolicy="LRU" statistics="true">
        <persistence strategy="localTempSwap" />
    </defaultCache>

    <cache name="studentCache" maxEntriesLocalHeap="10000" eternal="false"
        timeToIdleSeconds="5" timeToLiveSeconds="10">
        <persistence strategy="localTempSwap" />
    </cache>

    <cache name="org.hibernate.cache.internal.StandardQueryCache"
        maxEntriesLocalHeap="5" eternal="false" timeToLiveSeconds="120">
        <persistence strategy="localTempSwap" />
    </cache>

</ehcache>

HibernateUtil.java

package com.nik.util;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;

public class HibernateUtil {
  
    private static SessionFactory sessionFactory;
  
     private static SessionFactory buildSessionFactory() {
            try {
                // Create the SessionFactory from hibernate.cfg.xml
                Configuration configuration = new Configuration();
                configuration.configure("hibernate.cfg.xml");
                ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
                SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
                return sessionFactory;
            }
            catch (Throwable ex) {
                System.err.println("SessionFactory creation failed." + ex);
                ex.printStackTrace();
                throw new ExceptionInInitializerError(ex);
            }
        }
       
        public static SessionFactory getSessionFactory() {
            if(sessionFactory == null) sessionFactory = buildSessionFactory();
            return sessionFactory;
        }
}


StudentServiceImpl.java

package com.nik.dao;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

import com.nik.model.StudentInfo;
import com.nik.util.HibernateUtil;

public class StudentServiceImpl {
    public static void main(String[] arg){
         SessionFactory sf = HibernateUtil.getSessionFactory(); 
         Session session = sf.openSession(); 
          
         session.beginTransaction(); 
          
         StudentInfo student = new StudentInfo(); 
         student.setStudentName("Nitesh Sahay");
          
             
         session.save(student); 
          
         session.getTransaction().commit(); 
         StudentInfo stu=(StudentInfo) session.load(StudentInfo.class, 1l);
         System.out.println(stu.getStudentName());
         session.close();
         session = sf.openSession();
         session.evict(stu); //evict student from 1st level cache if any
         session.clear();//clear 1st level cache
         stu=(StudentInfo) session.load(StudentInfo.class, 1l);
        
         System.out.println(stu.getStudentName());
        
         System.out.println(stu.getStudentName());
         session.close();
         sf.close();
        }



}

Output:




Saturday 13 December 2014

Hibernate First Level cache Example

Hibernate first level cache is available to the same valid hibernate session . So it means all the objects which are in persistent state are available in first level cache until and unless the session is clear or objects are evicted from the session.Hibernate by default provide the First level cache . Here is the live example to explain the fact.

Using the previous  posted example... http://hibernate4us.blogspot.in/2012/12/simple-hibernate-example-here-i-am.html

FirstLevelCacheIlluastrationClass.java

public class FirstLevelCacheIlluastrationClass {
public static void main(String[] arg){
 Configuration configuration = new Configuration();
     SessionFactory    sessionFactory =configuration.buildSessionFactory();
    Session session=sessionFactory.openSession();
    Transaction tx=null;
    tx.beginTransaction();
    StudentClass stuObject=new StudentClass();
    stuObject.setStudentName("Nitesh Sahay");
    String studentId=session.save(stuObject);
    tx.commit();

    stuObject=null;
    stuObject=session.load(StudentClass.class,studentId);;//Able to get the student //from First level cache
    System.out.println(stuObject.getStudentName());
    session.close();
    try{
         System.out.println(stuObject.getStudentName());
}catch(Exception e){
   e.printStackTrace();//session already closed... no proxy
}

}
}



Friday 2 August 2013

StatelessSession Interface

StatelessSession Interface

If you want to avoid the high level of hibernate life cycle and the persistance level
then StatelessSession(org.hibernate.StatelessSession) is the solution.It neglects the 1st level and second level of cache.It works similar to org.hibernate.Session .
The link for the Java Doc is this.
 
{
StatelessSession session = sessionFactory.openStatelessSession();
Transaction tx = session.beginTransaction();
   
ScrollableResults students = session.createQuery("from STUDENT").scroll();
    
while ( students.next() ) {
    Student std = (Student) students.get(0);
    session.update(std);
}
   
tx.commit();
session.close();
} 
 


Saturday 2 March 2013

Update table using HQL

Update table using HQL

This example of code is using the previous hibernate configuration ,orm file and Java class file


  try {
           Session session=HibernateSessionFactory.getSessionFactory().openSession();
           Transaction tx=session.beginTransaction();
            String hql = "UPDATE StudentClass s SET s.studentName= :newName WHERE s.studentId= :studentID";
           // String hql="UPDATE StudentClass  SET studentName= :newName WHERE //studentId= :studentID";
            Query query = session.createQuery(hql);
            query.setParameter("studentID", new Long(1));
            query.setParameter("newName "Nitesh sahay");
            int rowCount = query.executeUpate();
            System.out.println("Rows affected: " + rowCount);
          
        } catch (java.lang.HibernateException ex) {
            ex.printStackTrace();
        }


Wednesday 5 December 2012

Simple Hibernate example

Simple Hibernate example

Here i am created  a simple hibernate example which include all the pojo,orm and hibernate-configuration


package com.nik.test

public class StudentInfo implements java.io.Serializable {

    private long studentId;
    private String studentName;

    public Student() {
    }

    public StudentInfo(String studentName) {
        this.studentName = studentName;
    }

    public long getStudentId() {
        return this.studentId;
    }

    public void setStudentId(long studentId) {
        this.studentId = studentId;
    }

    public String getStudentName() {
        return this.studentName;
    }

    public void setStudentName(String studentName) {
        this.studentName = studentName;
    }

}




The ORM(object relational mapping) file is as follows:
Student.hbm.xml



<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>

<class name="com.nik.test.StudentClass" table="STUDENT">
    <meta attribute="class-description">
    This class contains the course details.
    </meta>
    <id name="studentId" type="long" column="studentID">
        <generator class="native"/>
    </id>
    <property name="studentName" type="string" column="studentName" not-null="true" />
</class>


</hibernate-mapping>




Hibernate configuration file is as follows:

hibenate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
                                         "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
 <session-factory name="">
  <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
  <property name="hibernate.connection.url">jdbc:mysql://localhost/testdb</property>
  <property name="hibernate.connection.username">root</property>
  <property name="connection.password"></property>
  <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
  <property name="hibernate.show_sql">true</property>
  <property name="hbm2ddl.auto">create</property>
  <mapping class="com.nik.test.StudentInfo" />
   
 </session-factory>
</hibernate-configuration>