Hibernate 5 Envers

In this tutorial you will learn about Hibernate 5 envers library and see real use with example code.

Hibernate 5 Envers

Hibernate 5 Envers - What is Hibernate 5 Envers library and How to use it?

In this section we will introduce you with the Hibernate 5 Envers library and teach you its usages with real Hibernate 5 based project. After completing this tutorial you will be able to use this library in your project and perform data auditing functionalities provided by this framework.

Hibernate Envers are one of the module which can be used Hibernate and JPA applications. This module can be used with Hibernate application of many different type, it can be used with standalone, web application, inside WildFly, Spring Framework applications etc..

What is Hibernate 5 Envers?

Hibernate Envers is a library that works with Hibernate/JPA for auditing the changes made to the Entity and enable the developer to get all the transactions made with the entity. For example suppose you have a table to store the address of an employee, in future employee address might change and data entry operator will update it with new data. If the entity (address) is versioned with Envers you can get all the previous data with the details of changes made to it.

So, its very promising project if you have such requirement of saving/keeping history of add the changes(transactions) made to the database.

This library is very easy to use and you just have to import the library in your project, add the annotation (@Audited) to the Entity and you are done. Hibernate 5 Envers library will take care of rest.

How to use Hibernate 5 Envers?

To use the Hibernate 5 Envers you can download the library and include in your project. But the easiest method is to use Maven with your project. If you are using Maven in your project then add following dependency in pom.xml file.

<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-envers</artifactId>
  <version>5.2.8.Final</version>
</dependency>

This will include the Hibernate Envers library into the project. Maven will download and install Hibernate Envers jar files into your project.

Enabling Auditing in Entity Class

Next step is to enable the Auditing in the Entity file. The annotation @Audited is used for enabling auditing in a class. Additionally you can also enable the auditing for some fields in the Entity class by just adding to @Audited annotation to the fields you want auditing.

In our example we are enabling the auditing of while Entity class. Here is the full code of our Entity class which is annotated with the @Audited annotation for auditing:

package net.roseindia.model;
import java.io.Serializable;

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.envers.Audited;
/**
 * @author Deepak Kumar
 * Web: http://www.roseindia.net
 */
@Entity
@Audited
@Table(name = "article")
public class Article implements Serializable{

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY) 
	@Column(name="id")
	private int id;	

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

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

	public int getId() {
		return id;
	}

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

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}	  

	
}

Above Entity maps to a table "article" and has some basic fields like id, title and content. In real projects you may have many more fields in the database table but just to simplicity I have used just three fields to make the things simpler.

Database table structure

In this example we are using article table in MySQL. Here is the sql script to create database table:

CREATE TABLE `article` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(45) DEFAULT NULL,
  `content` varchar(400) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

You can use above query to create table in MySQL database.

Hibernate configuration file

In the hibernate.cfg.xml file we will add following code:

<property name="hibernate.hbm2ddl.auto">update</property>

This will enable Hibernate to create the tables necessary for auditing of data. In the example it will create following three tables:

  1. article_aud
  2. hibernate_sequence
  3. tbl_revinfo

All these tables will be used by Hibernate Envers to keep copy of changed data. This process is automatically handled by Hibernate 5 Envers library in your project. This makes life of developer very simple when there is need of development of such application.

Here is full code of hibernate.cfg.xml file used in our project:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-5.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/hibernate5</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<property name="hibernate.connection.pool_size">10</property>
<property name="show_sql">true</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.current_session_context_class">thread</property>


<mapping class="net.roseindia.model.Article" />

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

Above hibernate.cfg.xml file perfectly works with the Hibernate 5 Envers. Now I will show you how to run this project.

Initializing Hibernate SessionFactory

Now in Hibernate 5 we will use the code given in the class HibernateUtil.java which actually bootstraps Hibernate and initializes the Hibernate SessionFactory instance.

Full source code of HibernateUtil.java:

package net.roseindia;

import org.hibernate.SessionFactory;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;


/**
 * @author Deepak Kumar 
 * Web: http://www.roseindia.net
 */
public class HibernateUtil {
private static final SessionFactory sessionFactory;

private static ServiceRegistry serviceRegistry;

static {
	try {
	StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder()
	.configure("hibernate.cfg.xml").build();
	Metadata metaData = new MetadataSources(standardRegistry).getMetadataBuilder().build();
	sessionFactory = metaData.getSessionFactoryBuilder().build();
	} catch (Throwable th) {
	System.err.println("Enitial SessionFactory creation failed" + th);
	throw new ExceptionInInitializerError(th);
	}
}

public static SessionFactory getSessionFactory() {

	return sessionFactory;

}
}

Above class will be used to get SessionFactory instance in our example code.

Running Hibernate 5 Envers Example

In the Eclipse you can run the class CreateData.java, which will create an new entity and save it using the Hibernate. Here is the full source code of CreateData.java:

package net.roseindia;

import org.hibernate.Session;
import org.hibernate.SessionFactory;

import net.roseindia.model.*;
/**
 * @author Deepak Kumar 
 * Web: http://www.roseindia.net
 */
public class CreateData {
	public static void main(String[] args) throws Exception {

	SessionFactory sessFact = HibernateUtil.getSessionFactory();
	Session session = sessFact.getCurrentSession();
	org.hibernate.Transaction tr = session.beginTransaction();
	Article article = new Article();
	article.setTitle("Java Tutorial");
	article.setContent("Read all tutorials at http://www.roseindia.net");

	session.save(article);
	tr.commit();
	System.out.println("Successfully inserted");
	sessFact.close();
	}

}

After successful run of the above code Hibernate will create following three tables in databse:

  1. article_aud
  2. hibernate_sequence
  3. tbl_revinfo

If you check these tables you will find appropriate data in these tables. Using these tables Hibernate Envers audits the table data.

In the next session we will learn how to query the audit log/versions of data from database.

Download source code of Hibernate 5 Envers Example.