use-case: when we need to compare two objects to check their equality for satisfying some business rules.

In hibernate, we need to take care of some more factors in addition to what we do in Core Java.

  • Hibernate mostly work with persistent objects only.
  • 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.)

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 = -123456789L;
   @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));
Output:
true

Now both objects are equal logically as well as programmatically.

Notes:

  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.