Hibernate Merging and Refreshing Entities

In previous tutorial, we learned about saving entities using save() or saveOrUpdate() methods in hibernate. There we learned that in most of the cases, you will not even need those methods as hibernate manages the updates on persistent entities automatically. You only need to care about transient objects in most of cases. In this tutorial, I am discussing few thoughts around refresh() and merge() method present in hibernate session class.

Refreshing Hibernate Entities Using refresh() Method

Sometimes we face situation where we application database is modified with some external application/agent and thus corresponding hibernate entity in your application actually becomes out of sync with it’s database representation i.e. having old data. In this case, you can use session.refresh() method to re-populate the entity with latest data available in database.

You can use one of the refresh() methods on the Session interface to refresh an instance of a persistent object, as follows:

public void refresh(Object object) throws HibernateException
public void refresh(Object object, LockMode lockMode) throws HibernateException

These methods will reload the properties of the object from the database, overwriting them. In real life applications, you do not have to use the refresh() method very often apart from above stated scenario.

Let’s look at an example of refresh() method.

public class RefreshEntityExample
{
   public static void main(String[] args)
   {
      Session sessionOne = HibernateUtil.getSessionFactory().openSession();
      sessionOne.beginTransaction();
      
      //Create new Employee object
      EmployeeEntity emp = new EmployeeEntity();
      emp.setEmployeeId(1);
      emp.setFirstName("Lokesh");
      emp.setLastName("Gupta");
      
      //Save employee
      sessionOne.save(emp);
      sessionOne.getTransaction().commit();
      sessionOne.close();
      
      //Verify employee's firstname
      System.out.println(verifyEmployeeFirstName(1, "Lokesh"));
      
      Session sessionTwo = HibernateUtil.getSessionFactory().openSession();
      sessionTwo.beginTransaction();
      
      //This 
      emp.setFirstName("Vikas");
      sessionTwo.refresh(emp);
      
      sessionTwo.getTransaction().commit();
      sessionTwo.close();
      
      System.out.println(emp.getFirstName().equals("Lokesh"));
      
      HibernateUtil.shutdown();
   }  
   
   private static boolean verifyEmployeeFirstName(Integer employeeId, String firstName){
      Session session = HibernateUtil.getSessionFactory().openSession();
      EmployeeEntity employee = (EmployeeEntity) session.load(EmployeeEntity.class, employeeId);
      //Verify first name
      boolean result = firstName.equals(employee.getFirstName());
      session.close();
      //Return verification result
      return result;
   }
}

Output:

true
true

Look above the highlighted lines.

  • Line 15 save the employee with first name “Lokesh”
  • Line 26 set the first name “Vikas”. As entity is detached, DB will not be updated.
  • Line 27 refresh the entity with database using refresh() method.
  • Line 32 verify that firstname set in entity has been updated with “Lokesh” as it is what database have this moment.

This was all about refresh method. Let’s look an another similar method merge().

Merging Hibernate Entities Using merge() Method

Method merge() does exactly opposite to what refresh() does i.e. It updates the database with values from a detached entity. Refresh method was updating the entity with latest database information. So basically, both are exactly opposite.

Merging is performed when you desire to have a detached entity changed to persistent state again, with the detached entity’s changes migrated to (or overriding) the database. The method signatures for the merge operations are:

Object merge(Object object)
Object merge(String entityName, Object object)

Hibernate official documentation give a very good explanation of merge() method:

Copy the state of the given object onto the persistent object with the same identifier. If there is no persistent instance currently associated with the session, it will be loaded. Return the persistent instance. If the given instance is unsaved, save a copy of and return it as a newly persistent instance. The given instance does not become associated with the session. This operation cascades to associated instances if the association is mapped with cascade=”merge”.

So if I take below code for example then below listed points should be clear to you.

EmployeeEntity mergedEmpEntity = session.merge(empEntity);
  • ’empEntity’ is detached entity when it is passed to merge() method.
  • merge() method will search for an already loaded EmployeeEntity instance with identifier information taken from empEntity. If such persistent entity is found then it will be used for updates. Other wise a new EmployeeEntity is loaded into session using same identifier information as present in ’empEntity’.
  • Data is copied from ’empEntity’ to new found/loaded entity.
  • Because new/found entity is persistent, all data copied to it from ’empEntity’ is automatically saved into database.
  • Reference of that new entity is returned from merge() method and is assigned to ‘mergedEmpEntity’ variable.
  • ’empEntity’ is still detached entity.
public class MergeEntityExample
{
   public static void main(String[] args)
   {
      Session sessionOne = HibernateUtil.getSessionFactory().openSession();
      sessionOne.beginTransaction();
      
      //Create new Employee object
      EmployeeEntity emp = new EmployeeEntity();
      emp.setEmployeeId(1);
      emp.setFirstName("Lokesh");
      emp.setLastName("Gupta");
      
      //Save employee
      sessionOne.save(emp);
      sessionOne.getTransaction().commit();
      sessionOne.close();
      
      //Verify employee's firstname
      System.out.println(verifyEmployeeFirstName(1, "Lokesh"));
      
      Session sessionTwo = HibernateUtil.getSessionFactory().openSession();
      sessionTwo.beginTransaction();
      
      //Set new first name
      emp.setFirstName("Vikas");
      
      //Merge the emp object using merge() method
      EmployeeEntity mergedPersistentEmpEntity = (EmployeeEntity) sessionTwo.merge(emp);
      
      sessionTwo.getTransaction().commit();
      sessionTwo.close();
      
      //Verify employee's firstname again in database
      System.out.println(verifyEmployeeFirstName(1, "Vikas"));
      
      HibernateUtil.shutdown();
   }  
   
   private static boolean verifyEmployeeFirstName(Integer employeeId, String firstName){
      Session session = HibernateUtil.getSessionFactory().openSession();
      EmployeeEntity employee = (EmployeeEntity) session.load(EmployeeEntity.class, employeeId);
      //Verify first name
      boolean result = firstName.equals(employee.getFirstName());
      session.close();
      //Return verification result
      return result;
   }
}

Output:

true
true

In above example, ‘mergedPersistentEmpEntity’ is new entity which is persistent. So if you want to any more change, then make in in ‘mergedPersistentEmpEntity’ instance.

That’s all for this tutorial covering merge() and refresh() methods in hibernate. Remember that question can be asked as difference between merge() and refresh(), or difference between merge() and load() etc. Be ready to encounter any such difference between interview questions.

Happy Learning !!

Was this post helpful?

Join 7000+ Awesome Developers

Get the latest updates from industry, awesome resources, blog updates and much more.

* We do not spam !!

17 thoughts on “Hibernate Merging and Refreshing Entities”

  1. Hi,

    I think here in ur example it is updating in case of merge only since u have specified the id manually if u use auto generated id then it will insert a new record instead of updating it.

    Reply
  2. Hi Kishore,
    Not sure If your doubt got cleared by this time or not. I came to see your question now, have gone through your code and got some clue on what might have happened.
    Actually session.get will cache the object loaded from database. so both emp1 and emp2 is cached here.
    I think it has taken the cached emp2 object. looks like refresh has not loaded the updated db employee object data here since its done on emp2 and not emp1. Not sure why so . need to research on this

    Thanks,
    nms

    Reply
  3. In the Example of Refresh:
    You changed the name to “Vikas”and made a refresh and then checking the firstName with “Lokesh”(that returns true).
    In my point of view you should check the first name with “Vikas” and it should return true at that time and should return false if checking with “Lokesh” as value is already updated after doing refresh.
    Please let me know if my understanding is wrong.

    Thanks

    Reply
  4. I think you should change your first line with
    In the previous tutorial, we learned about saving entities using persist() methods in hibernate.

    thanks

    Reply
  5. All this tutorials are very helpful and its great that there are simple and concrete examples.

    Thank you!

    My only suggestion would be to review the order of the tutorials because its not sorted. For example, this tutorial refers to a previous tutorial but save/saveOrUpdate tutorial actually comes after if one follows the menu “Hibernate Tutorial” – on the top left of this page (which also does not seem to be organized).

    Once more, this is only one detail and one can easily find what he wants. The content of the tutorials is amazing, and thank you for sharing 🙂

    Reply
  6. I like your tutorial,only thing i will suggest you to give previous and next button in the end of each tutorial. Because if we are going through the index in right side its not in the order.

    Thanks

    Reply

Leave a Comment

HowToDoInJava

A blog about Java and related technologies, the best practices, algorithms, and interview questions.