В чем разница между удалением каскада и сироты из БД?

Какая разница между

@OneToMany(cascade=REMOVE, mappedBy="customer")
public List<Order> getOrders() { ... }

и

@OneToMany(mappedBy="customer", orphanRemoval="true")
public List<Order> getOrders() { ... }

Этот пример из учебника Java EE, но я до сих пор не понимаю деталей.

Ответ 1

От здесь: -

Каскадное удаление

Маркировка опорного поля с CascadeType.REMOVE(или CascadeType.ALL, который включает REMOVE) указывает, что операции удаления должны быть автоматически каскадируются объекты сущностей, на которые ссылается поле (объекты нескольких объектов могут ссылаться на коллекцию поле):

@Entity
class Employee {
     :
    @OneToOne(cascade=CascadeType.REMOVE)
    private Address address;
     :
}

Удаление сирот

JPA 2 поддерживает дополнительный и более агрессивный режим удаления каскадов который может быть указан с помощью элемента orphanRemoval @OneToOne и @OneToMany аннотации:

@Entity
class Employee {
     :
    @OneToOne(orphanRemoval=true)
    private Address address;
     :
}

РАЗНИЦА: -

Разница между двумя настройками заключается в ответе на отключая связь. Например, например, при настройке адресное поле в null или в другой объект Address.

  • Если указано orphanRemoval = true, удаленный экземпляр адреса автоматически удаляется. Это полезно для очистки зависимые объекты (например, адрес), которые не должны существовать без ссылку с объекта владельца (например, Employee).
  • Если указано только cascade = CascadeType.REMOVE, автоматическое действие не выполняется, так как отсоединение отношения не является удалением
    работа.

Ответ 2

Простой способ понять разницу между CascadeType.REMOVE и orphanRemoval=true.

Для удаления сирот: Если вы вызываете setOrders(null), связанные объекты Order будут автоматически удалены в db.

Для удаления каскада: Если вы вызываете setOrders(null), связанные объекты Order будут NOT удаляться автоматически в db.

Ответ 3

Предположим, у нас есть дочерняя сущность и родительская сущность. Родитель может иметь несколько детей.

@Entity
class parent {
  //id and other fields
 @OneToMany (orphanRemoval = "true",cascade = CascadeType.REMOVE)
   List<Personnel> myChildernList;
}

orphanRemoval - это концепция ORM, которая сообщает, является ли ребенок сиротой. его также следует удалить из базы данных.

Ребенок становится сиротой, когда к нему нельзя получить доступ от его родителя. Например, если мы удалим obj по индексу я (используя myChildernList.remove(i)) или установим его в null или заменим его новым (staffList.set(i, newChild)), то родительский элемент больше не сможет получить доступ к этому дочернему элементу. и ребенок осиротел, так что ребенок также обречен на удаление из базы данных (это душераздирающе :()

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

Ответ 4

Практически разница заключается в том, пытаетесь ли вы обновить данные (PATCH) или полностью заменить данные (PUT).

Допустим, вы удалите customer чем использование cascade=REMOVE также удалит заказы клиентов, которые кажутся полезными и полезными.

@OneToMany(cascade=REMOVE, mappedBy="customer")
public List<Order> getOrders() { ... }

Теперь предположим, что вы обновили customer с помощью orphanRemoval="true" он удалит все предыдущие заказы и заменит их на предоставленный. (PUT с точки зрения REST API)

@OneToMany(mappedBy="customer", orphanRemoval="true")
public List<Order> getOrders() { ... }

Без orphanRemoval старые заказы. (PATCH с точки зрения REST API)