Hibernate: проблема с каскадным удалением для отношения один ко многим - PullRequest
0 голосов
/ 10 марта 2019

У меня есть следующая модель сущности.

@Entity
@Table(name="product")
public class ProductEntity {
      @Id
      @GeneratedValue(generator = "uuid2")
      @GenericGenerator(name = "uuid2", strategy = "uuid2")
      private UUID id;

      ...


      @OneToMany(mappedBy = "productEntity", cascade = CascadeType.ALL)
      private List<ProductAddonEntity> productAddonEntities;
 }


@Entity
@Table(name="product_addon")
public class ProductAddonEntity {
      @Id
      @GeneratedValue(generator = "uuid2")
      @GenericGenerator(name = "uuid2", strategy = "uuid2")
      private UUID id;

      ...


      @ManyToOne()
      @JoinColumn(name = "addon_id")
      private ProductEntity addonEntity;
 }

Я хочу удалить продукт, и это удаление должно также удалить все объекты ProductAddon, связанные с этим продуктом. Поэтому я объявляю связь один ко многим со всеми каскадными типами. Но когда я пытаюсь удалить какой-либо продукт, в начале Hibernate пытается установить нулевой addon_id в таблице product_addon. Но этот столбец имеет ненулевое ограничение, поэтому удаление невозможно.

Поэтому я добавил в аннотацию @ManyToOne параметры

    @JoinColumn(name = "addon_id", nullable = false, updatable = false)

Но теперь hibernate просто пытается удалить продукт, прежде чем удалять сущности product_addon, связанные с этим продуктом. И это удаление не выполняется из-за ограничения внешнего ключа (Невозможно удалить или обновить родительскую строку: ограничение внешнего ключа не выполнено).

В чем здесь проблема? Это приложение также использует liquibase, поэтому внешние ключи генерируются не Hibernate. Например, внешний ключ для addon_id не имеет действий при удалении, но я думаю, что hibernate не нуждается в этих действиях, потому что он работает на более высоком уровне данных

1 Ответ

0 голосов
/ 10 марта 2019

Удаление-сирота - это агрессивный каскадный режим удаления для удаления дочернего объекта всякий раз, когда необходимо удалить родительский объект (отношения @OneToOne и @OneToMany).Эта функция добавлена ​​в версии JPA 2.0. Операция удаления JPA

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

@Entity   
class Employee {

@OneToOne(cascade=CascadeType.REMOVE)
private Address address;

}

Если указан только cascade = CascadeType.REMOVE, автоматическое действие не выполняется, поскольку отключение отношения не является операцией удаления.

@Entity
class Employee {

@OneToOne(orphanRemoval=true)
private Address address;

}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...