Home Hibernate Merge - Re attaching detached Entities

Merge – Re attaching detached Entities

- Advertisement -

Merge the state of the given entity into the current persistence context. The merge method’s major task is to transfer the state from an unmanaged entity (detached entity) to its managed counterpart within the persistence context. In other words merge will reattach the detached entity to the persistence context.

merge can only be called on Entity objects, not on Embeddable objects, or collections, or non-persistent objects.  Embeddable objects are automatically merged as part of their owning Entity.

How merge works?

When you call merge method,

  • if the entity is transient, it is saved and a persistent copy is returned.
  • if the given entity is persistent, means already in persistence context, no action is taken, but cascade operation still takes place.
  • if the entity state is detached, a copy of entity from existing persistence context returned, if an object with the same identifier exist in the current entity manager, then the state of the detached object is copied into the current persistent entity, and current entity is returned

For better understanding see JPA entity life cycle.

jpa hibernate entity or object lifecycle, entity states

Code Example :

jpa hibernate hello world example

Technologies Used in following example :

  • JPA 2.1
  • Hibernate 5.2.6
  • MySql 8.0
  • Maven 3
  • Spring Tool Suite (STS) 3.9.8
  • Java 1.8

Mapping Student.java

@Entity(name="STUDENT")
public class Student {
    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "native")
    @GenericGenerator(name = "native", strategy = "native"))
    @Column(name = "ID")
    private Long studentId;
    
    @Column(name = "FNAME")
    private String firstName;
    
    @Column(name = "LNAME")
    private String lastName;
    
    @Column(name = "CONTACT_NO")
    private String contactNo;

     // Getters and Setters
}

Testing Merge operation :

/**
 * JPA Merge Entity
 *
 */
public class App 
{
    public static void main( String[] args )
    {
        EntityManagerFactory emf = null;
        EntityManager entityManager = null;
        EntityTransaction transaction = null;
        
        try{
            emf = Persistence.createEntityManagerFactory("jbd-pu");
            entityManager = emf.createEntityManager();
            transaction = entityManager.getTransaction();
            transaction.begin();
            
            /* When ever EntityManager's find() calls the state of Student instance will be "Persistent" */
            Student student = entityManager.find(Student.class, 2L);
            entityManager.clear();// Clears all managed entities in the persistence context to become detached.
            
            student.setLastName("Vincent");
            Student student2 = entityManager.merge(student);
            
            student.setLastName("Milanovich");//dosen't affect anything as student entity detached with persistence context
            System.err.println("is student in Persistence Context : "+entityManager.contains(student));
            System.err.println("is student2 in Persistence Context : "+entityManager.contains(student2));
            transaction.commit();
        }catch(Exception e){
            transaction.rollback();
        }finally{
            entityManager.close();
            emf.close();
        }
    }
}

Console Output :

INFO - HHH000400: Using dialect: org.hibernate.dialect.MySQLInnoDBDialect
INFO - HHH000397: Using ASTQueryTranslatorFactory
Hibernate: select student0_.ID as ID1_0_0_, student0_.CONTACT_NO as CONTACT_2_0_0_, student0_.FNAME as FNAME3_0_0_, student0_.LNAME as LNAME4_0_0_ from STUDENT student0_ where student0_.ID=?
Hibernate: select student0_.ID as ID1_0_0_, student0_.CONTACT_NO as CONTACT_2_0_0_, student0_.FNAME as FNAME3_0_0_, student0_.LNAME as LNAME4_0_0_ from STUDENT student0_ where student0_.ID=?
is student exists in Persistence Context : false
is student2 exists in Persistence Context : true
Hibernate: update STUDENT set CONTACT_NO=?, FNAME=?, LNAME=? where ID=?
INFO - HHH000030: Cleaning up connection pool [jdbc:mysql://localhost:3306/jpa_JBD]

References

  1. Java_Persistence

Satish Varma
Satish Varmahttps://javabydeveloper.com
Satish is post graduated in master of computer applications and experienced software engineer with focus on Spring, JPA, REST, TDD and web development. Also founder of javabydeveloper.com. Follow him on LinkedIn or Twitter or Facebook

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Stay in Touch

Categories