Establecer huérfanoRemoval en verdadero al migrar hijos de sus padres a otro padre

Noticia importante : Si estás leyendo esta publicación, entonces considera investigaresta publicación También para discusiones en profundidad.

Es una práctica / situación / requisito bastante habitual donde los hijos de un padre pueden migrar a otro padre. Qué pasa siorphanRemoval se establece entrue en el lado inverso de tales relaciones?

Considere, por ejemplo, cualquier relación simple de uno a muchos de la siguiente manera.

Lado inverso (departamento):

@OneToMany(mappedBy = "department", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private List<Employee> employeeList = new ArrayList<Employee>(0);

Propietario (Empleado):

@JoinColumn(name = "department_id", referencedColumnName = "department_id")
@ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH, CascadeType.DETACH})
private Department department;

Al fusionar una operación / acción como la siguiente (dondedepartment es una entidad separada suministrada por un cliente),

Employee employee = entityManager.find(Employee.class, 1L);
Department newDepartment = entityManager.contains(department) ? department : entityManager.merge(department);

if (!newDepartment.equals(employee.getDepartment())) {
    employee.getDepartment().getEmployeeList().remove(employee);
    // Since orphanRemoval is set to true, 
    // this should cause a row from the database table to be removed inadvertently
    // by issuing an addition DELETE DML statement.
}

employee.setDepartment(newDepartment);
employee.setEmployeeName("xyz");        

List<Employee> employeeList = newDepartment.getEmployeeList();

if (!employeeList.contains(employee)) {
    employeeList.add(employee);
}

entityManager.merge(employee);

Por supuesto, agregar y eliminar a un empleado puede hacerse / manejarse mejor usando métodos de gestión de enlace defensivo (relación) en las entidades asociadas.

Una instancia de departamento es suministrada por un cliente. Es una entidad separada. Puede ser el mismo departamento o un departamento diferente dependiendo de una acción administrativa realizada por el cliente en cuestión. Como resultado, si la instancia de departamento suministrada por un cliente es diferente de la que tiene el actualEmployee, debe eliminarse primero de la lista de empleados (employeeList) en poder de la corrienteantiguo departamento en el lado inverso asociado con esoEmployee antes de agregarlo a la lista de empleados en poder del nuevodepartment suministrado.

Como una suposición, elEmployee la fila debe eliminarse inadvertidamente de la base de datos mientras se eliminaEmployee instancia de la lista de empleados a los que hace referencia actualmente el departamento del empleado: departamento anterior (antes de que esta operación se haya activado), es decir, al migrar un niño de su padre a otro padre, el niño necesita ser eliminado de su padre nativo antes de que sea adoptado por otro padre y se supone que esa fila secundaria se elimina de la base de datos sin darse cuenta (orphanRemoval = true)

Sin embargo, la fila de empleados en la tabla de la base de datos permanece intacta con los valores de columna actualizados. No hay declaraciones DML excepto unUPDATE declaración se generan.

¿Puedo considerar que la migración de niños de su padre a otro padre de esta manera no elimina accidentalmente a esos niños de la tabla de la base de datos como deberían?no ¿ser?

Actualmente usando EclipseLink 2.6.0 con JPA 2.1.

EDITAR:

Si unaEmployee la entidad solo se elimina (por lo tanto, no se agrega a la lista después de que se eliminó, no se migró a otro padre sino que se eliminó) de la lista en el lado inverso, luego su fila correspondiente también se elimina de la base de datos como de costumbre (orphanRemoval = true) pero la fila simplemente se actualiza cuando unEmployee entidad (hijo) se agrega a la lista de otro padre después de que se eliminó de la lista de su padre nativo (migración de la entidad).

El proveedor parece ser lo suficientemente inteligente como para detectar la migración de niños de sus padres a otro padre, como una actualización.

El comportamiento se puede ver idéntico en Hibernate (4.3.6 final) y EclipseLink (2.6.0) pero no se puede confiar en él si es un comportamiento específico del proveedor (no portátil). No puedo encontrar nada sobre este comportamiento en la especificación JPA.

Respuestas a la pregunta(1)

Su respuesta a la pregunta