Hibernate - SPLessons

Chapter 21

Hibernate Locking

Hibernate Locking

Hibernate Locking, When multiple users are working on same data concurrently, then one user changes can be overridden by the another user. At this time, Hibernate is used as Locking Mechanism.If at a time multiple users working on same data then the disadvantage is lost of data.Hibernate has two types of Locking Mechanism.

Optimistic Locking

Optimistic locking prevents the concurrent changes of one user by another user by using the version object.

  • Hibernate Locking, will maintain a version of an object in a separate column of table.
  • When a new object is persisted to the database. Then, Hibernate will assign its version Zero to the database, when it is updated, hibernate increments version by 1.
  • Using the version object in POJO class, it should be defined in int type.
  • In hbm file, one need to map a version property to version column of a table using <version> tag.
  • <Version> tag is defined under<id> tag in hbm file.
  • In <class>tag, add the optimistic-lock attribute.
  • In optimistic locking, before committing the changes of a user to the database, Hibernate verifies whether the version of the user and version of a database is same or not.If same then commits the changes of that user in database.If not matched then hibernate throws StaleObjectStateException.
  • In Optimistic locking time, total table is locked.

For example, take the User1 and User2, both two users concurrently works on the same database. Then, the result will be inconsistency in the database.
Create the Project directory structure.
Create a table in Database with name splessons2 and insert the rows in Database.

Create the persistance class.

SPLessons.java

package com.itoolsinfo;

public class SPLessons 
{
  
	private int id;
	private String name;
	private int version;
	public int getVersion() {
		return version;
	}
	public void setVersion(int version) {
		this.version = version;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

Here the developer created the class SPLessons and also created id by giving integer datatype and name by giving Sting and also used set and get methods, Set and Get methods are a pattern of data encapsulation. Instead of accessing class member variables directly, one can define get methods to access these variables, and set methods to modify them.

Map the persistence class in mapping file that is splessons5.hbm.xml.

   
<?xml version='1.0' encoding='UTF-8'?>
<!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.itoolsinfo.SPLessons" table="splessons2&" optimistic-lock="version">     
 <id name="id" column="id">    
 <generator class="assigned">    
 </generator>   
 </id>    
 <version name="version" type="int"/>;    
 <property name="name">    
 </property>      
 </class>         
 </hibernate-mapping>     

Configure the mapping file in Configuration file.

hibernate.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"	 	 
 "property name="connection.driver_class">	 	 
 oracle.jdbc.driver.OracleDriver	 	 
 </proper>	 	
 <property name="connection.url">	 	 
 jdbc:oracle:thin:@localhost:1521:XE	 	 
 </property> 	
 <property name="connection.username">	 	 
 system	 	 
 </property>	 	  
 <property name="connection.password">	 	 
 system	 	
</property> 	
 <property name="dialect"> 	 
 org.hibernate.dialect.Oracle10gDialect	 	 
 </property>	 	  
 <property name="hibernate.hbm2ddl.auto">	 	 
 create	 	
 </property>	 
 <property name="show_sql">	 	 
 true	 	 
 </property>	 	
 <mapping resource="splessons5.hbm.xml"/>	 	 
 </session-factory>	 	 
 	 	 
</hibernate-configuration>	 	
   
Properties Description
hibernate.connection.driver_class The JDBC driver class.
hibernate.dialect This property makes Hibernate generate the suitable SQL for the picked database.
hibernate.connection.url The JDBC URL to the database instance.
hibernate.connection.username The database username.
hibernate.connection.password The database password.
hibernate.connection.pool_size Limits the number of connections waiting in the Hibernate database connection pool.
hibernate.connection.autocommit Allows autocommit mode to be used for the JDBC connection.

Create the User1 class and perform update operation on database.

User1.java

package com.itoolsinfo;

import javax.swing.JOptionPane;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class User1 
{
	public static void main(String args[])
{
	SessionFactory factory=new Configuration().configure("hibernate.cfg.xml").configure().buildSessionFactory();
	         Session session=factory.openSession();
	         SPLessons splessons = (SPLessons) session.get(SPLessons.class, 1);
	 	   Transaction transaction = session.beginTransaction();

          
                 String str = JOptionPane.showInputDialog("Enter name:user1");
                // JOptionPane is used the open the dialgue box at run time.
	 		   splessons.setName(str);
	 		   transaction.commit();
	 		   session.close();
	 		  factory.close();
	 	}
	 }

JOptionPane is used the open the dialogue box at run time. Application acquires session objects from Session Factory. SessionFactory is for the most part arranged as Singleton in application, SessionFactory stores produce SQL statements and other mapping metadata that Hibernate utilizes at runtime.

Create the User2 class and perform the update operation on database.

User2.java

package com.itoolsinfo;

import javax.swing.JOptionPane;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class User1 
{
	public static void main(String args[])
{
	SessionFactory factory=new Configuration().configure("hibernate.cfg.xml").configure().buildSessionFactory();
	         Session session=factory.openSession();
	         SPLessons splessons = (SPLessons) session.get(SPLessons.class, 1);
	 		Transaction transaction = session.beginTransaction();
        
	 	String str = JOptionPane.showInputDialog("Enter name:user2");
                 // JOptionPane is used the open the dialogue box at run time.
	 		   
                    splessons.setName(str);
	 		   transaction.commit();
	 		   session.close();
	 		  factory.close();
           }
	 }

Pessimistic Locking

In pessimistic Locking, at the time of selecting the data, a user will acquire a lock on the row for updating the data. The other user can read the data of that row, but can’t change the data until lock is released by the user before.

  • If the other user Transaction is committing the changes, then that transaction would be in waiting state, either until lock is released or a lock time out period exceeds.
  • At the time of reading a record from a table, if a user want to get a Lock on that row. Then, a 3rd variable is passed to the get()/load() methods as a LOCKOPTIONS.UPGRADE.
  • In pessimistic locking, only total row is locked.
  • In Pessimistic locking, one cannot use any <versioning> tag or property column.
  • By default, pessimistic lock conflicitly happens LockTimeOutException and is tossed promptly. The “javax.persistence.lock.timeout” and indication can be set to permit sitting tight for a pessimistic lock for a predetermined number of milliseconds. This time period is mapped the mapping document.

[/alertmessages]


For example, take two users.User1 is locked for some time.

Create a table in Database with name splessons2 and insert the rows in Database.

Create the project directory structure.

Create the Persistence class

SPLessons.java

package com.itoolsinfo;

public class SPLessons 
{
  private int empid;
  private String empName;

public int getEmpid() {
	return empid;
}
public void setEmpid(int empid) {
	this.empid = empid;
}
public String getEmpName() {
	return empName;
}
public void setEmpName(String empName) {
	this.empName = empName;
}
}

Here used set and get methods for the employee id and employee name, Set and Get methods are a pattern of data encapsulation. Instead of accessing class member variables directly, one can define get methods to access these variables, and set methods to modify them.


To map the persistence class in mapping file that is .splessons4.hbm.xml

<?xml version='1.0' encoding='UTF-8'>     
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">    
     
 <hibernate-mapping>     <hibernate-mapping> 
 <class name="com.itoolsinfo.SPLessons" table="splessons1"optimistic-lock="version">     
 <id name="empId" column="id">      
 <generator class="increment">    
 </generator>    
 </id>    
 <property name="empName">    
 </property>  
 </class>    
 </hibernate-mapping>    

The generator class subelement of id utilized to produce the unique identifier for the objects of persistence class. There are numerous generator classes characterized in the Hibernate Framework. All the generator classes actualizes the org.hibernate.id.IdentifierGenerator interface.


Configure the mapping file in Configuration file.

hibernate.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>
           <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>  
           <property name="connection.url">jdbc:oracle:thin:@localhost:1521:XE</property>
          <property name="connection.username">system</property>  
          <property name="connection.password">system</property> 
        
       <property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>  
       <property name="hibernate.hbm2ddl.auto">create</property>  
       <property name="show_sql">true</property>  
        
      <mapping resource="splessons4.hbm.xml"/>
    </session-factory>  
  </hibernate-configuration>  
Properties Description
hibernate.connection.driver_class The JDBC driver class.
hibernate.dialect This property makes Hibernate generate the suitable SQL for the picked database.
hibernate.connection.url The JDBC URL to the database instance.
hibernate.connection.username The database username.
hibernate.connection.password The database password.
hibernate.connection.pool_size Limits the number of connections waiting in the Hibernate database connection pool.
hibernate.connection.autocommit Allows autocommit mode to be used for the JDBC connection.


Create the User1 class and update the value in database.

User1.java

package com.itoolsinfo;

import javax.swing.JOptionPane;

import org.hibernate.LockOptions;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class User1 
{
	public static void main(String args[])
{
	SessionFactory factory=new Configuration().configure("hibernate.cfg.xml").configure().buildSessionFactory();
	         Session session=factory.openSession();
	        
			SPLessons splessons = (SPLessons) session.get(SPLessons.class, 1, LockOptions.UPGRADE);
	 		
	 		Transaction transaction = session.beginTransaction();
        
	 	String str = JOptionPane.showInputDialog("Enter name:user1");
	 		   splessons.setEmpName(str);
	 		   transaction.commit();
	 		   session.close();
	 		  factory.close();
	 	}
	 }

A transaction basically speaks to a unit of work. In such case, in the event that one stage fizzles, the entire exchange falls flat (which is named as atomicity). An exchange can be portrayed by ACID properties (Atomicity, Consistency, Isolation and Durability).


Create the User2 class and Update the value on User1 and User2 concurrently.

User2.java

package com.itoolsinfo;

import javax.swing.JOptionPane;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class User2 
{
	public static void main(String args[])
    {
	SessionFactory factory=new Configuration().configure("hibernate.cfg.xml").configure().buildSessionFactory();
	         Session session=factory.openSession();
	         SPLessons splessons = (SPLessons) session.get(SPLessons.class, 1);
	 		
	 	  Transaction transaction = session.beginTransaction();
        
	 	String str = JOptionPane.showInputDialog("Enter name:user2");
               //JOptionPane is used the open the Dialogue box at run time.
	 		   
                        splessons.setEmpName(str);
	 		   transaction.commit();
	 		   session.close();
	 		  factory.close();
	 	}
	 }


Summary

  • Hibernate Locking – Optimistic Hibernate Locking is a strategy where you read a record.