Close

JPA - Merging Detached Entity State

[Last Updated: Nov 21, 2017]

The changes made to a detached entity (last tutorial) can be synchronized to the database by using EntityManager.merge(detachedEntity).

EntityManager.merge(newInstance) can also be used on a new entity instance which has a valid database id.

Calling this method on a removed entity (tutorial here) will throw IllegalArgumentException.

EntityManager.merge() method is cascaded to entities referenced by this entity if the attribute cascade=ALL or cascade=MERGE are used (check out cascading tutorial).

Example

The Entity

@Entity
public class Employee {
    @Id
    @GeneratedValue
    private Integer id;
    private String name;
    private String department;

    public Employee() {
    }

    public Employee(String name, String department) {
        this(null, name, department);
    }

    public Employee(Integer id, String name, String department) {
        this.name = name;
        this.department = department;
        this.id = id;
    }
    .............
}

Persisting, merging and loading

public class ExampleMain {

    static EntityManagerFactory emf =
            Persistence.createEntityManagerFactory("example-unit");

    public static void main(String[] args) {
        Employee employee = new Employee("Sara Dorsey", "Admin");
        persistEmployee(employee);
        //employee at this point is detached but still has database id
        employee.setDepartment("Account");
        //merging
        updateEmployee(employee);
        //loading
        Employee employee2 = loadEmployeeById(employee.getId());
        print("Employee loaded", employee2);
        //creating new updated instance
        Employee employee3 = new Employee(employee.getId(), employee.getName(), "Sales");
        //merging
        updateEmployee(employee3);
        //loading again
        Employee employee4 = loadEmployeeById(employee.getId());
        print("Employee loaded", employee4);

        emf.close();
    }

    private static Employee loadEmployeeById(int id) {
        System.out.println("-- loading employee by id --");
        EntityManager em = emf.createEntityManager();
        return em.find(Employee.class, id);
    }

    private static void updateEmployee(Employee employee) {
        System.out.println("-- merging employee --");
        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();
        em.merge(employee);
        em.getTransaction().commit();
        print("Employee merged", employee);
    }

    private static void persistEmployee(Employee employee) {
        System.out.println("-- persisting employee --");
        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();
        em.persist(employee);
        em.getTransaction().commit();
        em.close();
        print("Employee persisted", employee);
    }

    private static void print(String msg, Object... objects) {
        System.out.printf("%s: %s%n", msg, Arrays.asList(objects));
    }
}
-- persisting employee --
Employee persisted: [Employee{id=1, name='Sara Dorsey', department='Admin'}]
-- merging employee --
Employee merged: [Employee{id=1, name='Sara Dorsey', department='Account'}]
-- loading employee by id --
Employee loaded: [Employee{id=1, name='Sara Dorsey', department='Account'}]
-- merging employee --
Employee merged: [Employee{id=1, name='Sara Dorsey', department='Sales'}]
-- loading employee by id --
Employee loaded: [Employee{id=1, name='Sara Dorsey', department='Sales'}]

Example Project

Dependencies and Technologies Used:

  • h2 1.4.196: H2 Database Engine.
  • hibernate-core 5.2.10.Final: The core O/RM functionality as provided by Hibernate.
    Implements javax.persistence:javax.persistence-api version 2.1
  • JDK 1.8
  • Maven 3.3.9

EntityManager#merge() Example Select All Download
  • merging-entities-example
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • ExampleMain.java
          • resources
            • META-INF

    See Also