2008-11-20 2 views
116

У меня возникли проблемы удаления узлов бесхозных с помощью JPA со следующим отображениемJPA CascadeType.ALL не удаляет сирот

@OneToMany (cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "owner") 
private List<Bikes> bikes; 

Я имею вопрос о осиротевших роли торчать в базе данных.

Я могу использовать аннотацию org.hibernate.annotations.Cascade Специфика Hibernate, но, очевидно, я не хочу привязывать свое решение к реализации Hibernate.

EDIT: Кажется, JPA 2.0 будет содержать поддержку для этого.

ответ

138

Если вы используете его с Hibernate, вам необходимо явно определить аннотацию CascadeType.DELETE_ORPHAN, которая может использоваться в сочетании с JPA CascadeType.ALL.

Если вы не планируете использовать Hibernate, вам придется сначала сначала удалить дочерние элементы, а затем удалить основную запись, чтобы избежать любых сиротских записей.

последовательность выполнения

  1. выборки основной строки будут удалены
  2. начнут извлекать дочерние элементы
  3. удалить все дочерние элементы
  4. удалить основной ряд
  5. близко сессия

С JPA 2.0, теперь вы можете использовать опцию orphanRemoval = истинный

@OneToMany(mappedBy="foo", orphanRemoval=true) 
+3

спасибо, я в конечном итоге будет этот путь, я думаю, это немного больше для спецификации JPA. – 2008-11-21 08:49:29

+12

В стандарте JPA 2.0 теперь есть deleteOrphan как атрибут @OneToMany Если вы используете последний спящий режим, вы можете сделать @OneToMany (..., deleteOrphan = true) – jomohke 2010-06-11 06:33:13

+0

Что такое последовательность выполнения, когда я просто обновляю дочерние элементы? будут ли удалены сироты? – jAckOdE 2014-05-26 07:22:53

104

Если вы используете JPA 2.0, теперь вы можете использовать атрибут @xxxToMany аннотацию orphanRemoval=true для удаления сирот.

На самом деле, CascadeType.DELETE_ORPHAN был устарел в 3.5.2-финале.

+3

+1 для обеспечения ответа uptodate на этот вопрос! – 2010-09-02 09:02:22

+5

На самом деле я думаю, что orphanRemoval = true означает что-то другое, т. Е. Удаляет объект, когда я удаляю его из коллекции его родителя. См. Http://download.oracle.com/javaee/6/tutorial/doc/bnbqa.html#giqxy – Archie 2010-09-13 22:37:43

+3

он не работает с @ManyToMany, как я знаю. – ses 2011-03-17 18:43:41

4

Я просто найти это решение, но в моем случае это не работает:

@OneToMany(cascade = CascadeType.ALL, targetEntity = MyClass.class, mappedBy = "xxx", fetch = FetchType.LAZY, orphanRemoval = true) 

orphanRemoval = истина не имеет никакого эффекта.

2

Всего @OneToMany(cascade = CascadeType.ALL, mappedBy = "xxx", fetch = FetchType.LAZY, orphanRemoval = true).

Удалить targetEntity = MyClass.class, это отлично работает.

1

Для записей в OpenJPA до JPA2 это было @ElementDependant.

7

вы можете использовать @PrivateOwned для удаления сирот например

@OneToMany(mappedBy = "masterData", cascade = { 
     CascadeType.ALL }) 
@PrivateOwned 
private List<Data> dataList; 
40
╔═════════════╦═════════════════════╦═════════════════════╗ 
║ Action ║ orphanRemoval=true ║ CascadeType.ALL ║ 
╠═════════════╬═════════════════════╬═════════════════════╣ 
║ delete ║  deletes parent ║ deletes parent ║ 
║ parent ║  and orphans  ║ and orphans  ║ 
╠═════════════╬═════════════════════╬═════════════════════╣ 
║ change ║      ║      ║ 
║ children ║ deletes orphans ║  nothing  ║ 
║ list  ║      ║      ║ 
╚═════════════╩═════════════════════╩═════════════════════╝ 
2

Я была такая же проблема, и я задавался вопросом, почему это условие ниже не удалял сирот. Перечень блюд не были удалены в Hibernate (5.0.3.Final), когда я выполнил именованный запрос на удаление:

@OneToMany(mappedBy = "menuPlan", cascade = CascadeType.ALL, orphanRemoval = true) 
private List<Dish> dishes = new ArrayList<>(); 

Тогда я вспомнил, что не должен использовать именованный запрос на удаление, но EntityManager. Поскольку я использовал метод EntityManager.find(...) для извлечения объекта, а затем EntityManager.remove(...), чтобы удалить его, посуда также была удалена.

0

Я использовал один к одному отображения, но ребенок не получал удален JPA давал внешнего ключа нарушение

После использования orphanRemoval = правда, вопрос был решен