Hibernate Interceptor

It is useful for the application to react to certain events that occur inside Hibernate. This allows for the implementation of generic functionality and the extension of Hibernate functionality. Hibernate Interceptor provides an API which one can implement to intercept various operation like save and delete of an entity.

The Interceptor interface provides callbacks from the session to the application, allowing the application to inspect and/or manipulate properties of a persistent object before it is saved, updated, deleted or loaded. One possible use for this is to track auditing information.

You can either implement Interceptor directly or extend EmptyInterceptor.

First create a new Java Project and configure it as Maven Project. For Reference, Click Here

Add the following dependencies in pom.xml

<dependencies>
 
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.8.2</version>
        <scope>test</scope>
    </dependency>
 
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.15</version>
    </dependency>
 
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>3.6.3.Final</version>
    </dependency>
 
    <dependency>
        <groupId>javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>3.12.1.GA</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.6.6</version>
    </dependency>
</dependencies>

1. Sql Script

Use the following Sql Script for creating table.

create table Employee(
    EMPLOYEE_ID int(10) primary key NOT NULL AUTO_INCREMENT,
    Name varchar(50));

2. Pojo

Now create Employee class.

package com.kruders.model.bean;
 
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

import javax.persistence.Table;
 
@Entity
@Table(name = "EMPLOYEE")
public class Employee {
    @Id
    @GeneratedValue(strategy= GenerationType.AUTO)
    @Column(name = "EMPLOYEE_ID")
    private int employeeId;
     
    @Column(name = "Name")
    private String name;
     
    public Employee() {
    }
    
    public Employee(String name) {
        this.name = name;
    }
    public int getEmployeeId() {
        return employeeId;
    }
    public void setEmployeeId(int employeeId) {
        this.employeeId = employeeId;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

3. Interceptor Class

Now Create a interceptor class MyInterceptor.java that extends the Hibernate EmptyInterceptor.

package com.kruders.interceptor;

import java.io.Serializable;
import java.util.Iterator;

import org.hibernate.EmptyInterceptor;
import org.hibernate.EntityMode;
import org.hibernate.type.Type;

import com.kruders.model.bean.Employee;

public class MyInterceptor extends EmptyInterceptor {
	
	// This method is called when Employee class is instantiated.
	public Object instantiate(String entityName, EntityMode entityMode, Serializable id) {
		System.out.println("Instantiating object in mode : " + entityMode);
		return null;
	}

	// This method is called when Employee object is deleted.
	public void onDelete(Object entity, Serializable id, Object[] state,
			String[] propertyNames, Type[] types) {
		if (entity instanceof Employee) {
			System.out.println("Employee Deleted");
		}
		
	}

	// This method is called when Employee object gets updated.
	public boolean onFlushDirty(Object entity, Serializable id,
			Object[] currentState, Object[] previousState,
			String[] propertyNames, Type[] types) {
		if (entity instanceof Employee) {
			System.out.println("Update Operation");
			return true;
		}
		return false;
	}

	// This method is called before Employee object is initialized.
	public boolean onLoad(Object entity, Serializable id, Object[] state,
			String[] propertyNames, Type[] types) {
		if (entity instanceof Employee) {
			System.out.println("Before Initialization");
			return true;
		}
		return true;
	}

	// This method is called when Employee object gets created.
	public boolean onSave(Object entity, Serializable id, Object[] state,
			String[] propertyNames, Type[] types) {
		if (entity instanceof Employee) {
			System.out.println("Employee Saved");
			return true;
		}
		return false;
	}

	// This method is called before commit into database
	public void preFlush(Iterator iterator) {
		System.out.println("Before Flushing");
	}

	// This method is called after committed into database
	public void postFlush(Iterator iterator) {
		System.out.println("After Flushing");
	}
	
	// This method is called when the flush() method is called on a Session object.
	public int[] findDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState,
			String[] propertyNames, Type[] types) {
		System.out.println("findDirty: Detects if object is dirty : " + entity);
		return null;
	}
}

There are two kinds of inteceptors: Session-scoped and SessionFactory-scoped.

A Session-scoped interceptor is specified when a session is opened using one of the overloaded SessionFactory.openSession() methods accepting an Interceptor.

Session session = sf.openSession(new MyInterceptor());

A SessionFactory-scoped interceptor is registered with the Configuration object prior to building theSessionFactory. Unless a session is opened explicitly specifying the interceptor to use, the supplied interceptor will be applied to all sessions opened from that SessionFactory. SessionFactory-scoped interceptors must be thread safe. Ensure that you do not store session-specific states, since multiple sessions will use this interceptor potentially concurrently.

new Configuration().setInterceptor(new MyInterceptor());

4. Hibernate Configuration File

Now create the hibernate configuration file and add all the mapping files.

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="hibernate.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"></property>
	<property name="connection.pool_size">1</property>
	<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
	<property name="show_sql">true</property>
	<mapping class="com.kruders.model.bean.Employee" />
</session-factory>
</hibernate-configuration>

5. Hibernate Utility Class


Now create HibernateUtil class. The HibernateUtil class helps in creating the SessionFactory from the Hibernate configuration file. A org.hibernate.SessionFactory is used to obtain org.hibernate.Session instances. A org.hibernate.Session represents a single-threaded unit of work. The org.hibernate.SessionFactory is a thread-safe global object that is instantiated once.

package com.kruders.util;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
  
public class HibernateUtil {
  
    private static final SessionFactory sessionFactory = buildSessionFactory();
  
    private static SessionFactory buildSessionFactory() {
        try {
            // Create the SessionFactory from hibernate.cfg.xml
            return new Configuration().configure().buildSessionFactory();
        } catch (Throwable ex) {
            // Make sure you log the exception, as it might be swallowed
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }
  
    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

6. Run Program

To enable Interceptor, pass MyInterceptor class as an argument while creating Session object as follows:

.openSession(new MyInterceptor())


Create Main.java class that perform CRUD operations and run it as Java Application

package com.kruders.core;

import java.util.Iterator;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;

import com.kruders.interceptor.MyInterceptor;
import com.kruders.model.bean.Employee;
import com.kruders.util.HibernateUtil;



public class Main {
	public static void main(String args[]) {
		Session session = HibernateUtil.getSessionFactory().openSession(new MyInterceptor());
		Transaction transaction = null;
		try {
			
			transaction = session.beginTransaction();
			Employee employee = new Employee("Puneet");
	        session.save(employee);   
	        transaction.commit();
		}catch (HibernateException e) {
			transaction.rollback();
			e.printStackTrace();
		} finally {
			session.close();
		}
		
		//updateEmployee("Puneet", "Raghav");
		//deleteEmployee(1);
	}
	
	public void updateEmployee(String oldName, String newName) {
		Session session = HibernateUtil.getSessionFactory().openSession();
		Transaction transaction = null;
        try {
             
            transaction = session.beginTransaction();
            List employees = session.createQuery("from Employee where Name ='" + oldName + "'").list();
            for (Iterator iterator = employees.iterator(); iterator.hasNext();) {
                Employee employee = (Employee) iterator.next();
                employee.setName(newName);
            }
            transaction.commit();
        } catch (HibernateException e) {
            transaction.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }
    }
	public void deleteEmployee(Integer employeeId) {
		Session session = HibernateUtil.getSessionFactory().openSession();
		Transaction transaction = null;
        try {
             
            transaction = session.beginTransaction();
            List employees = session.createQuery("from Employee where employeeId ='" + employeeId + "'").list();
            for (Iterator iterator = employees.iterator(); iterator.hasNext();) {
                Employee employee = (Employee) iterator.next();
                session.delete(employee);
            }
            transaction.commit();
        } catch (HibernateException e) {
            transaction.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }
     }
}

7. Output

Insert Operation

Employee Saved
Hibernate: insert into EMPLOYEE (Name) values (?)
Before Flushing
findDirty: Detects if object is dirty : com.kruders.bean.Employee@d1c778
After Flushing


Update Operation

Hibernate: select employee0_.EMPLOYEE_ID as EMPLOYEE1_0_, employee0_.Name as Name0_ from EMPLOYEE employee0_ where Name=’Puneet’
Instantiating object in mode : pojo
Before Initialization
Before Flushing
findDirty: Detects if object is dirty : com.kruders.bean.Employee@eaf40c
Update Operation
Hibernate: update EMPLOYEE set Name=? where EMPLOYEE_ID=?
After Flushing


Delete Operation

Hibernate: select employee0_.EMPLOYEE_ID as EMPLOYEE1_0_, employee0_.Name as Name0_ from EMPLOYEE employee0_ where employee0_.EMPLOYEE_ID=’5′
Instantiating object in mode : pojo
Before Initialization
Employee Deleted
Before Flushing
findDirty: Detects if object is dirty : com.kruders.bean.Employee@50a649
Hibernate: delete from EMPLOYEE where EMPLOYEE_ID=?
After Flushing

The folder structure of the example is shown below in Figure 19.1

Figure 19.1 Figure 19.1

You can download the source code of this example here.

No comments yet.

Leave a Reply