Checking Hibernate Entity Equality between Sessions

Many times in our application, we face a situation where we have to compare two instances to check their equality for satisfying some business rules. In core java, we have hashCode() and equals() methods checking the equality of objects. But in hibernate, we need to take care of a few extra things as well.

Let’s learn what are those extra things we need to consider while implementing the entity identity and equality rules.

1. Managed Entities Represent Database Rows

We have already learned about hibernate entity lifecycle state. We know that hibernate tracks and manages the persistent objects only. Also, we know that a persistent object represents two things:

  • An instance of a class in a particular Java virtual machine (JVM)
  • A row (or rows) in a database table (or tables)

In runtime, the current Session instance is responsible for fetching, storing and managing an instance of an entity. As an entity represents a database row, it is worth noting that if we fetch the same row over and over again, there is no new Entity instance is created in the same Session. Rather, Session refreshes the existing entity instance and its fields information.

The above fact plays an important role in deciding how to compare entity instances within the same session or different sessions.

2. Entity Instances Fetched in Same Session

Requesting a persistent object again from the same Hibernate session returns the same Java instance of the entity class, which means that we can compare the objects using the standard Java ‘==‘ equality syntax.

Let’s see a quick example:

public static void main(String[] args)
{
	Session sessionOne = HibernateUtil.getSessionFactory().openSession();
	sessionOne.beginTransaction();

	// Create new Employee object
	EmployeeEntity emp = new EmployeeEntity();
	emp.setFirstName("Lokesh");
	emp.setLastName("Gupta");
	//Save employee
	sessionOne.save(emp);

	sessionOne.getTransaction().commit();

	//Get employee id
	Integer empId = emp.getEmployeeId();

	//New session where we will fetch the employee two times and compare the objects
	Session sessionTwo = HibernateUtil.getSessionFactory().openSession();
	sessionTwo.beginTransaction();

	EmployeeEntity employeeObj1 = (EmployeeEntity) sessionTwo.get(EmployeeEntity.class, empId);
	EmployeeEntity employeeObj2 = (EmployeeEntity) sessionTwo.get(EmployeeEntity.class, empId);

	//Checking equality
	System.out.println(employeeObj1 == employeeObj2);      //TRUE

	HibernateUtil.shutdown();
}

You see above that we got two instances on EmployeeEntity and both are actually the same java object instance.

2. Entity Instances Fetched in Different Sessions

If you request a persistent object from more than one Hibernate session, Hibernate will provide distinct instances from each session, and the == operator will return false if you compare these object instances.

Let’s compare instances “emp” and “employeeObj1” in above example and you will get the result as false; because both are fetched in separate sessions.

System.out.println(emp == employeeObj1);           //FALSE
System.out.println(emp.equals(employeeObj1));  //FALSE

So if we are comparing objects in two different sessions, we will need to implement the equals() method on your Java persistence objects, which we should do as a best practice anyway. (Just don’t forget to override hashCode() along with it.)

Hibernate wraps the actual object in a proxy so always use the getter methods instead of directly accessing the fields inside the hashCode() and equals() methods.

Now let’s add equals() method as suggested and then see the behavior change while checking the equality of both instances on EmployeeEntity.

@Entity
@Table(name = "Employee")
public class EmployeeEntity implements Serializable
{
   private static final long serialVersionUID = -1798070786993154676L;
   @Id
   @Column(name = "ID", unique = true, nullable = false)
   @GeneratedValue(strategy = GenerationType.SEQUENCE)
   private Integer           employeeId;
   @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;

   @Override
   public boolean equals(Object o) {
       if (this == o) return true;
       if (!(o instanceof EmployeeEntity)) return false;

       EmployeeEntity otherEmployee = (EmployeeEntity) o;

       if (getEmployeeId() != null ?
           !getEmployeeId().equals(otherEmployee.getEmployeeId()) : otherEmployee.getEmployeeId() != null)
           return false;
       if (getFirstName() != null ?
           !getFirstName().equals(otherEmployee.getFirstName()) : otherEmployee.getFirstName() != null)
           return false;
       if (getLastName() != null ?
           !getLastName().equals(otherEmployee.getLastName()) : otherEmployee.getLastName() != null)
           return false;

       return true;
   }

   @Override
   public int hashCode() {
   int result = getEmployeeId() != null ? getEmployeeId().hashCode() : 0;
       result = 31 * result + (getFirstName() != null ? getFirstName().hashCode() : 0);
       result = 31 * result + (getLastName() != null?getLastName().hashCode() : 0);
       return result;
   }

   //Setters and Getters
}

Now let’s again check the equality using equals() method. [‘==’ will return false, we know that].

System.out.println(emp.equals(employeeObj1));    //TRUE

Now both objects are equal logically as well as programmatically.

4. Conclusion

  1. Requesting a persistent object again from the same Hibernate session returns the “same instance” of a class.
  2. Requesting a persistent object from the different Hibernate sessions returns the “different instances” of a class.
  3. As a best practice, always implement equals() and hashCode() methods in the hibernate entities; and always compare them using equals() method only.

Happy Learning !!

Leave a Reply

0 Comments
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions, and frequently asked interview questions.

Our Blogs

REST API Tutorial