Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA Updating Bidirectional Association

Lets assume we have the following Entities:

    @Entity
    public class Department {

        @OneToMany(mappedBy="department")
        private List<Employee> employees;
    }

    @Entity
    public class Employee {

        @ManyToOne
        private Department department
    }

It is understandable on an update that we need to maintain both sides of the relationship as follows:

Employee emp = new Employee();
Department dep = new Department();
emp.setDepartment(dep);
dep.getEmployees().add(emp);

All good up till now. The question is should I apply merge on both sides as follows, and an I avoid the second merge with a cascade?

entityManager.merge(emp);
entityManager.merge(dep);

Or is merging the owning side enough? Also should these merges happen inside a Transaction or EJB? Or doing it on a simple controller method with detached entities is enough?

like image 671
ChrisGeo Avatar asked Nov 19 '13 10:11

ChrisGeo


1 Answers

The question is should I apply merge on both sides as follows, and an I avoid the second merge with a cascade?

You can use the cascade annotation element to propagate the effect of an operation to associated entities. The cascade functionality is most typically used in parent-child relationships.

The merge operation is cascaded to entities referenced by relationships from Department if these relationships have been annotated with the cascade element value cascade=MERGE or cascade=ALL annotation.

Bidirectional relationships between managed entities will be persisted based on references held by the owning side (Employee) of the relationship. It is the developer’s responsibility to keep the in-memory references held on the owning side (Employee) and those held on the inverse side (Department) consistent with each other when they change. So, with below series of statements, the relationship will be synchronized to the database with a single merge:

Employee emp = new Employee();
Department dep = new Department();
emp.setDepartment(dep);
dep.getEmployees().add(emp);
...
entityManager.merge(dep);

These changes will be propagated to database at transaction commit. The in-memory state of the entities can be synchronized to the database at other times as well when a transaction is active by using the EntityManager#flush method.

like image 120
Debojit Saikia Avatar answered Oct 17 '22 23:10

Debojit Saikia