JPA CascadeType.ALL не удаляет сирот
У меня возникли проблемы с удалением сиротских узлов с использованием JPA со следующим отображением
@OneToMany (cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "owner")
private List<Bikes> bikes;
У меня возникла проблема с сиротскими ролями, которые висят вокруг базы данных.
Я могу использовать тег аннотации org.hibernate.annotations.Cascade
Hibernate, но, очевидно, я не хочу привязывать свое решение к реализации Hibernate.
EDIT. Кажется, JPA 2.0 будет содержать поддержку для этого.
Ответы
Ответ 1
Если вы используете его с Hibernate, вам нужно будет явно определить аннотацию CascadeType.DELETE_ORPHAN
, которую можно использовать в сочетании с JPA CascadeType.ALL
.
Если вы не планируете использовать Hibernate, вам придется сначала сначала удалить дочерние элементы, а затем удалить основную запись, чтобы избежать любых сиротских записей.
последовательность выполнения
- выберите основную строку для удаления
- выборка дочерних элементов
- удалить все дочерние элементы
- удалить основную строку
- закрыть сеанс
С JPA 2.0 теперь вы можете использовать опцию orphanRemoval = true
@OneToMany(mappedBy="foo", orphanRemoval=true)
Ответ 2
Если вы используете JPA 2.0, теперь вы можете использовать атрибут orphanRemoval=true
аннотации @xxxToMany
для удаления сирот.
Собственно, CascadeType.DELETE_ORPHAN
устарел в 3.5.2-Final.
Ответ 3
╔═════════════╦═════════════════════╦═════════════════════╗
║ Action ║ orphanRemoval=true ║ CascadeType.ALL ║
╠═════════════╬═════════════════════╬═════════════════════╣
║ delete ║ deletes parent ║ deletes parent ║
║ parent ║ and orphans ║ and orphans ║
╠═════════════╬═════════════════════╬═════════════════════╣
║ change ║ ║ ║
║ children ║ deletes orphans ║ nothing ║
║ list ║ ║ ║
╚═════════════╩═════════════════════╩═════════════════════╝
Ответ 4
Если вы используете JPA с EclipseLink, вам нужно будет задать аннотацию @PrivateOwned.
Документация: Eclipse Wiki - Использование расширений JPA EclipseLink - Глава 1.4 Как использовать @PrivateOwned Annotation
Ответ 5
вы можете использовать @PrivateOwned для удаления сирот
например
@OneToMany(mappedBy = "masterData", cascade = {
CascadeType.ALL })
@PrivateOwned
private List<Data> dataList;
Ответ 6
Согласно Java Persistence with Hibernate, каскадное сиротское удаление недоступно в виде аннотации JPA.
Он также не поддерживается в JPA XML.
Ответ 7
Я просто нашел это решение, но в моем случае он не работает:
@OneToMany(cascade = CascadeType.ALL, targetEntity = MyClass.class, mappedBy = "xxx", fetch = FetchType.LAZY, orphanRemoval = true)
orphanRemoval = true не имеет эффекта.
Ответ 8
Просто @OneToMany(cascade = CascadeType.ALL, mappedBy = "xxx", fetch = FetchType.LAZY, orphanRemoval = true)
.
Удалите targetEntity = MyClass.class, он прекрасно работает.
Ответ 9
У меня была такая же проблема, и я задавался вопросом, почему это условие ниже не удаляло сирот. Список блюд не был удален в Hibernate (5.0.3.Final), когда я выполнил именованный запрос на удаление:
@OneToMany(mappedBy = "menuPlan", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Dish> dishes = new ArrayList<>();
Затем я вспомнил, что я не должен использовать именованный запрос на удаление, но EntityManager. Поскольку я использовал метод EntityManager.find(...)
для извлечения объекта, а затем EntityManager.remove(...)
, чтобы удалить его, посуда также была удалена.
Ответ 10
Для записей в OpenJPA перед JPA2 это было @ElementDependant.
Ответ 11
Я использовал одно к одному сопоставление, но ребенок не получал удаленный JPA давал нарушение внешнего ключа
После использования orphanRemoval = true проблема решена.