Given below a one-to-many relationship from Department
to Employee
.
Department (parent) :
@OneToMany(mappedBy = "department", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List<Employee> employeeList = new ArrayList<Employee>(0);
Employee (child) :
@JoinColumn(name = "department_id", referencedColumnName = "department_id")
@ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH, CascadeType.DETACH})
private Department department;
Merging a managed entity (child) like the following (using CMT in EJB),
Employee employee = entityManager.find(Employee.class, 1L);
employee.setDepartment(department); // department is supplied by a client.
employee.setEmployeeName("xyz");
entityManager.merge(employee);
does not update the corresponding employee row in the database table. It happens only when CascadeType.MERGE
is removed from the child @ManyToOne
relationship in Employee
.
Why doesn't the row in the table get updated? What is the sole purpose of CascadeType.MERGE
regarding this example?
I am currently using EclipseLink 2.6.0 having JPA 2.1.
Cascading should always propagate from a Parent to a Child and not the other way around.
In your case, you need to remove the Cascade from the child-side:
@JoinColumn(name = "department_id", referencedColumnName = "department_id")
@ManyToOne(fetch = FetchType.LAZY)
private Department department;
and make sure you set both sides of the association:
Employee employee = entityManager.find(Employee.class, 1L);
employee.setDepartment(department);
employee.setEmployeeName("xyz");
department.getEmployeeList().add(employee);
entityManager.merge(department);