Я немного запутался в orphanRemoval
атрибуте JPA 2.0 .
Я думаю, что вижу, что это необходимо, когда я использую инструменты генерации БД моего провайдера JPA для создания базовой базы данных DDL, чтобы иметь отношение ON DELETE CASCADE
к конкретному отношению.
Однако, если БД существует и уже имеет отношение ON DELETE CASCADE
on, этого недостаточно для надлежащего каскадного удаления? Что делает orphanRemoval
в дополнение?
ура
источник
Пример взятой формы здесь :
Когда
Employee
объект сущности удаляется, операция удаления каскадно относится кAddress
объекту ссылочной сущности. В связи с этимorphanRemoval=true
иcascade=CascadeType.REMOVE
идентичны, и, еслиorphanRemoval=true
указано,CascadeType.REMOVE
является излишним.Разница между этими двумя настройками заключается в ответе на разрыв отношения. Например, например, при установке поля адреса на
null
или на другойAddress
объект.Если
orphanRemoval=true
указано, отключенныйAddress
экземпляр автоматически удаляется. Это полезно для очистки зависимых объектов (напримерAddress
), которые не должны существовать без ссылки от объекта-владельца (напримерEmployee
).Если
cascade=CascadeType.REMOVE
указано только , автоматическое действие не выполняется, так как отключение отношения не является операцией удаления.Чтобы избежать висячих ссылок в результате удаления осиротевших, эта функция должна быть включена только для полей, которые содержат частные не общие зависимые объекты.
Я надеюсь, что это делает это более ясным.
источник
В тот момент, когда вы удаляете дочернюю сущность из коллекции, вы также удаляете эту дочернюю сущность из БД. orphanRemoval также подразумевает, что вы не можете сменить родителей; если есть отдел, в котором есть сотрудники, то после того, как вы удалите этого сотрудника, чтобы перевести его в другой отдел, вы по неосторожности удалите этого сотрудника из БД с помощью команды flush / commit (что произойдет раньше). Мораль заключается в том, чтобы установить для orphanRemoval значение true, если вы уверены, что дети этого родителя не будут мигрировать к другому родителю на протяжении всего своего существования. Включение orphanRemoval также автоматически добавляет REMOVE в каскадный список.
источник
department.remove(emp);
этот сотрудник будет удален из таблицы emp, даже не позвонивcommit()
Эквивалентное отображение JPA для DDL
ON DELETE CASCADE
естьcascade=CascadeType.REMOVE
. Удаление без учета означает, что зависимые объекты удаляются, когда связь с их «родительским» объектом уничтожается. Например, если ребенок удален из@OneToMany
отношения без явного удаления его в менеджере сущностей.источник
cascade=CascadeType.REMOVE
НЕ является эквивалентомON DELETE CASCADE
. On делает удаление в коде приложения и не влияет на DDL, другие выполняются в БД. См. Stackoverflow.com/a/19696859/548473Разница в следующем:
- orphanRemoval = true: дочерняя сущность удаляется, когда на нее больше нет ссылок (ее родительская часть не может быть удалена).
- CascadeType.REMOVE: «Дочерняя» сущность удаляется только тогда, когда ее «Родитель» удаляется.
источник
Переходы состояния объекта
JPA переводит переходы состояния сущности в операторы SQL, такие как INSERT, UPDATE или DELETE.
Когда вы являетесь
persist
сущностью, вы планируете выполнение оператора INSERT приEntityManager
сбросе, автоматически или вручную.когда вы являетесь
remove
сущностью, вы планируете инструкцию DELETE, которая будет выполняться, когда сбрасывается контекст постоянства.Каскадные переходы состояний объекта
Для удобства JPA позволяет распространять переходы состояний сущностей от родительских сущностей к дочерним.
Итак, если у вас есть родительский
Post
объект, который@OneToMany
связан сPostComment
дочерним объектом:comments
Коллекция вPost
сущности, отображается следующим образом :CascadeType.ALL
cascade
Атрибут сообщает поставщик JPA передать объект состояние перехода от родительскогоPost
объекта для всехPostComment
лиц , содержащихся вcomments
коллекции.Итак, если вы удалите
Post
сущность:Поставщик JPA собирается
PostComment
сначала удалить объект, а когда все дочерние объекты будут удалены, он также удалитPost
объект:Удаление сирот
Когда вы устанавливаете
orphanRemoval
атрибут вtrue
, поставщик JPA собирается планироватьremove
операцию, когда дочерняя сущность удаляется из коллекции.Итак, в нашем случае,
Поставщик JPA собирается удалить связанную
post_comment
запись, поскольку наPostComment
объект больше не ссылаются вcomments
коллекции:НА УДАЛЕННОМ КАСКАДЕ
ON DELETE CASCADE
Определяется на уровне FK:Как только вы это сделаете, если вы удалите
post
строку:Все связанные
post_comment
сущности автоматически удаляются ядром базы данных. Однако это может быть очень опасной операцией, если вы по ошибке удалите корневую сущность.Вывод
Преимущество JPA
cascade
иorphanRemoval
опций заключается в том, что вы также можете воспользоваться оптимистичной блокировкой для предотвращения потери обновлений .Если вы используете механизм каскадирования JPA, вам не нужно использовать уровень DDL
ON DELETE CASCADE
, что может быть очень опасной операцией, если вы удалите корневую сущность, которая имеет много дочерних сущностей на нескольких уровнях.Для более подробной информации по этой теме, проверьте эту статью .
источник
CascadeType
. Это дополнительный механизм. Теперь вы ошибаетесь с удалением с сохранением. Удаленное удаление - это удаление не связанных ссылок, а сохранение - сохранение новых объектов. Вам нужно перейти по ссылкам, приведенным в ответе, чтобы лучше понять эти понятия.@GaryK ответ абсолютно отличный, я потратил час на поиски объяснения
orphanRemoval = true
против,CascadeType.REMOVE
и это помогло мне понять.Подводя итог:
orphanRemoval = true
работает идентичноCascadeType.REMOVE
ТОЛЬКО ЕСЛИ мы удаляем object (entityManager.delete(object)
) и хотим, чтобы дочерние объекты также были удалены.В совершенно ином случае, когда мы выбираем некоторые данные, такие как,
List<Child> childs = object.getChilds()
а затем удаляем child (entityManager.remove(childs.get(0)
),orphanRemoval=true
это приводит к тому, что соответствующий объектchilds.get(0)
будет удален из базы данных.источник
Удаление сирот имеет тот же эффект, что и ON DELETE CASCADE в следующем сценарии: - Допустим, у нас простое отношение «многие к одному» между сущностью студента и сущностью-гидом, где многие ученики могут быть сопоставлены с одним и тем же руководством, и в базе данных есть отношение внешнего ключа между таблицей Student и Guide так, что для таблицы Student есть id_guide в виде FK.
// родительский объект
В этом сценарии отношение таково, что объект учащегося является владельцем отношения, и поэтому нам необходимо сохранить объект учащегося, чтобы сохранить весь граф объекта, например
Здесь мы отображаем одно и то же руководство с двумя разными объектами учеников, и поскольку используется CASCADE.PERSIST, граф объектов будет сохранен, как показано ниже в таблице базы данных (MySql в моем случае)
СТУДЕНЧЕСКИЙ стол: -
ID Имя Dept Id_Guide
1 Рой ЕЭК 1
2 ник ECE 1
Таблица руководств: -
ID NAME Зарплата
1 Джон 1500 долларов
и теперь, если я хочу удалить одного из студентов, используя
и когда запись о студенте удаляется, соответствующая запись о руководстве также должна быть удалена, вот где атрибут CASCADE.REMOVE в сущности «Студент» входит в изображение и что он делает, он удаляет студента с идентификатором 1, а также соответствующий объект-указатель (идентификатор) 1). Но в этом примере есть еще один объект ученика, который сопоставлен с той же направляющей записью, и если мы не используем атрибут orphanRemoval = true в объекте Guide, приведенный выше код удаления не будет работать.
источник