Hibernate Entities Equality and Identity

Many times in our application, we face a situation where we have to compare two objects to check their equality for satisfying some business rules. In core java, we have already much knowledge about checking equality of objects, but in hibernate we need to take care of few extra things as well. Let’s learn what are those extra concepts.

We already learned about various states of hibernate entities in their life-cycle. There we discussed that hibernate mostly work with persistent objects only. As we know that when we have a persistent object in hibernate, that object represents both :

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

We know enough around first concept. I will focus on second point.

Objects fetched from same session

Requesting a persistent object again from the same Hibernate session returns the same Java instance of a class, which means that you 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 genEmpId = 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, genEmpId);
	EmployeeEntity employeeObj2 = (EmployeeEntity) sessionTwo.get(EmployeeEntity.class, genEmpId);

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

	HibernateUtil.shutdown();
}

Output:

true

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

Objects fetched from 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);
System.out.println(emp.equals(employeeObj1));

Output:

false
false

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

Read More: Overriding hashCode() and equals() methods

Hibernate wraps the actual object in a proxy so always use the getter methods inside instead of actual properties to compare.

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 lets again check the equality using equals() method. [‘==’ will return false, we know that].

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

Output:

true

Now both objects are equal logically as well as programmatically.

Bullet Points

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

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.

5 thoughts on “Hibernate Entities Equality and Identity”

  1. What if firstName was a lazy loaded entity? Will using it in equals not hit the database?
    Or more precisely, how to deal with lazy loaded objects in equals method.

    Reply
  2. i did not see any extra equality check. As per java standards we have override both equals and hashcode to represents objects absolutely same in jVM

    Reply

Leave a Comment

HowToDoInJava

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