Установка orphanRemoval в true при переносе детей от их родителей к другому родителю

Важное замечание : Если вы читаете этот пост, подумайтеэта почта слишком для углубленных обсуждений.

Это довольно обычная практика / ситуация / требование, когда дети одного из родителей могут быть перемещены к другому родителю. Что будет, еслиorphanRemoval установлен вtrue на обратной стороне таких отношений?

Рассмотрим в качестве примера любое простое отношение «один ко многим» следующим образом.

Обратная сторона (отдел):

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

Собственная сторона (Сотрудник):

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

При объединении операции / действия, как показано ниже (гдеdepartment является отдельным объектом, предоставленным клиентом),

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);

Конечно, добавление и удаление сотрудника может быть лучше выполнено / обработано с использованием методов управления защитными связями (связями) в связанных объектах.

Экземпляр отдела предоставляется клиентом. Это отдельная сущность. Это может быть тот же или другой отдел в зависимости от административного действия, выполняемого данным клиентом. В результате, если экземпляр отдела, предоставленный клиентом, отличается от того, который хранится у текущегоEmployeeзатем его следует сначала удалить из списка сотрудников (employeeList) проводится текущимстарый отдел с обратной стороны, связанный с этимEmployee перед добавлением его в список сотрудников, занимаемых новымdepartment в комплект поставки.

Как предположение,Employee строка должна быть случайно удалена из базы данных при удаленииEmployee экземпляр из списка сотрудников, на который в данный момент ссылается старый отдел отдела (до того, как эта операция была запущена), т. е. при переносе дочернего элемента из родительского в другой родительский дочерний элемент должен быть удален из исходного родительского элемента до того, как принят другим родителем, и эта дочерняя строка должна быть случайно удалена из базы данных (orphanRemoval = true).

Однако строка сотрудника в таблице базы данных остается неизменной с обновленными значениями столбца. Нет операторов DML, кромеUPDATE оператор генерируется.

Могу ли я подумать, что миграция детей от своего родителя к другому родителю таким образом не приведет к непреднамеренному удалению этих детей из таблицы базы данных, как они должныне быть?

В настоящее время используется EclipseLink 2.6.0 с JPA 2.1.

РЕДАКТИРОВАТЬ:

ЕслиEmployee сущность только удаляется (то есть, не добавляется в список после того, как была удалена - не переносится на другого родителя, а просто удаляется) из списка на обратной стороне, затем соответствующая строка удаляется из базы данных также, как обычно (orphanRemoval = true) но строка просто обновляется, когдаEmployee сущность (дочерний элемент) добавляется в список другого родителя после того, как он был удален из списка его родного родителя (миграция сущности).

Поставщик, по-видимому, достаточно умен, чтобы обнаружить миграцию детей от их родителей к другому родителю в качестве обновления.

Поведение может быть идентичным как в Hibernate (4.3.6 final), так и в EclipseLink (2.6.0), но на него нельзя полагаться, если это поведение, специфичное для провайдера (не переносимое). Я не могу найти ничего об этом поведении в спецификации JPA.

Ответы на вопрос(1)

Ваш ответ на вопрос