JPA CascadeType.ALL не удаляет сирот - PullRequest
129 голосов
/ 20 ноября 2008

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

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

У меня проблема с осиротевшими ролями, висящими вокруг базы данных.

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

РЕДАКТИРОВАТЬ : Кажется, JPA 2.0 будет включать поддержку для этого.

Ответы [ 11 ]

154 голосов
/ 21 ноября 2008

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

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

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

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

В JPA 2.0 теперь вы можете использовать опцию orphanRemoval = true

@OneToMany(mappedBy="foo", orphanRemoval=true)
111 голосов
/ 28 мая 2010

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

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

43 голосов
/ 29 октября 2013
╔═════════════╦═════════════════════╦═════════════════════╗
║   Action    ║  orphanRemoval=true ║   CascadeType.ALL   ║
╠═════════════╬═════════════════════╬═════════════════════╣
║   delete    ║     deletes parent  ║    deletes parent   ║
║   parent    ║     and orphans     ║    and orphans      ║
╠═════════════╬═════════════════════╬═════════════════════╣
║   change    ║                     ║                     ║
║  children   ║   deletes orphans   ║      nothing        ║
║    list     ║                     ║                     ║
╚═════════════╩═════════════════════╩═════════════════════╝
12 голосов
/ 01 сентября 2009

Если вы используете JPA с EclipseLink, вам придется установить аннотацию @ PrivateOwned .

Документация: Eclipse Wiki - Использование расширений EclipseLink JPA - Глава 1.4 Как использовать аннотацию @PrivateOwned

7 голосов
/ 08 июля 2011

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

@OneToMany(mappedBy = "masterData", cascade = {
        CascadeType.ALL })
@PrivateOwned
private List<Data> dataList;
4 голосов
/ 06 октября 2010

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

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

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

4 голосов
/ 20 ноября 2008

Согласно Сохранение Java с Hibernate , каскадное удаление сирот недоступно в качестве аннотации JPA.

Также не поддерживается в JPA XML.

2 голосов
/ 01 ноября 2015

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

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

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

2 голосов
/ 11 декабря 2010

Просто @OneToMany(cascade = CascadeType.ALL, mappedBy = "xxx", fetch = FetchType.LAZY, orphanRemoval = true).

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

1 голос
/ 18 мая 2011

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

...