Hibernate @NaturalId Example Tutorial

Hibernate 4 has bring lots of improvements and @NaturalId is one of such nice improvements. As you know @Id annotation is used as meta data for specifying the primary key of an entity. But sometimes, entity is usually used in DAO layer code with id which not not primary key but its logical or natural id. In such cases, @NaturalId annotation will prove good replacement of named queries in hibernate.

For example, in any application there can be an employee entity. In this case, primary key will definitely be “employee id” but in cases such as login by email, user will provide email and password. In this case, in stead of writing named query, you can directly use @NaturalId annotation on “email” field.

How it works

If you look at logs then you will know that when you get an entity by its natural id then

  1. First primary key of entity is found by executing where clause of natural id
  2. This primary key is used fetch the information of entity

Example Usage

Let’s take this example.

For reference, latest hibernate maven dependency is as follows:

<dependency>
	<groupId>org.hibernate</groupId>
	<artifactId>hibernate-core</artifactId>
	<version>4.3.0.Beta3</version>
</dependency>

Now, a minimum employee entity will look like this:

EmployeeEntity.java

@Entity
@Table(name = "Employee", uniqueConstraints = {
		@UniqueConstraint(columnNames = "ID"),
		@UniqueConstraint(columnNames = "EMAIL") })
public class EmployeeEntity implements Serializable {
	
	private static final long serialVersionUID = -1798070786993154676L;
	
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "ID", unique = true, nullable = false)
	private Integer employeeId;
	
	//Use the natural id annotation here
	@NaturalId (mutable = false)
	@Column(name = "EMAIL", unique = true, nullable = false, length = 100)
	private String email;
	
	@Column(name = "FIRST_NAME", unique = false, nullable = false, length = 100)
	private String firstName;
	
	@Column(name = "LAST_NAME", unique = false, nullable = false, length = 100)
	private String lastName;

	//Setters and Getters
}

Now, lets see how to use this in code:

TestHibernate.java

public class TestHibernate
{
	public static void main(String[] args) 
	{
		Session session = HibernateUtil.getSessionFactory().openSession();
		session.beginTransaction();
       
		//Add new Employee object
		EmployeeEntity emp = new EmployeeEntity();
		emp.setEmail("demo-user@mail.com");
		emp.setFirstName("demo");
		emp.setLastName("user");
		//Save entity
		session.save(emp);
		
		EmployeeEntity empGet = (EmployeeEntity) session.bySimpleNaturalId( EmployeeEntity.class ).load( "demo-user@mail.com" );
		
		System.out.println(empGet.getFirstName());
		System.out.println(empGet.getLastName());
		
		session.getTransaction().commit();
		HibernateUtil.shutdown();
	}
}

Output in console:

Hibernate: insert into Employee (EMAIL, FIRST_NAME, LAST_NAME) values (?, ?, ?)

Hibernate: select employeeen_.ID as ID1_0_ from Employee employeeen_ where employeeen_.EMAIL=?

Hibernate: select employeeen0_.ID as ID1_0_0_, employeeen0_.EMAIL as EMAIL2_0_0_, employeeen0_.FIRST_NAME as FIRST3_0_0_, employeeen0_.LAST_NAME as LAST4_0_0_ from Employee employeeen0_ where employeeen0_.ID=?

demo
user

To download the source code of above tutorial, please click on below download link.

Sourcecode Download

Happy Learning !!

Was this post helpful?

Join 7000+ Fellow Programmers

Subscribe to get new post notifications, industry updates, best practices, and much more. Directly into your inbox, for free.

6 thoughts on “Hibernate @NaturalId Example Tutorial”

  1. If we use @naturalId, then Hibernate will fire two queries, which in turn increase load on DB, So I think, it is not an improvement just a burden.

    P.s. If I am wrong please correct me with good explanation.

    Reply

Leave a Comment

HowToDoInJava

A blog about Java and its related technologies, the best practices, algorithms, interview questions, scripting languages, and Python.