JPA: 'CascadeType.REMOVE' или 'orphanRemoval = true', которые используют в отношении: n, которое генерирует новую таблицу / класс с классом EmbeddeId? - PullRequest
0 голосов
/ 10 июня 2019

Я разрабатываю REST API для пиццерии. И здесь я пытаюсь удалить аромат и все данные, связанные с ним. Далее поясняется ниже:

Классы:

  • Flavor имеют по крайней мере один Filling, каждый из которых занимает позицию на нем.

    • Т.е.: соус (в поз. 1), моцарелла (в поз. 2) помидор (в поз. 3)
  • Flavor s должен иметь цену для каждого Size

Имея это в виду, мы можем заключить, что существуют два отношения «многие ко многим»:

  • Flavor ко многим Filling
  • Flavor ко многим Size

Диаграмма классов фактической реализации

Требуется: удалить Flavor и автоматически удалить все FillingPositionFlavor и FlavorPriceSize.

Но я запутался в использовании CascadeType.REMOVE и orphanRemoval = true:

Когда я использую Cascade и OrphanRemoval на Flavor.sizePrices, получаю HibernateException при попытке отредактировать Flavor, исключение работает нормально: A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance: com.pkg.Flavor.sizePrices

Когда я использую Cascade для Flavor.sizePrices, получаю исключение PSQLExx при исключении Flavor, редактирование работает нормально: ERROR: update or delete on table "tb_flavor" violates foreign key constraint "fk9orw0yhtc0e06ka84dbcd2c82" on table "tb_flavor_size_price"

Я выполняю модульное тестирование сервисов в Spring Boot для тестирования всех операций CRUD.

Ниже приведен фактический код, я спрятал свойства, такие как id и другие, чтобы облегчить чтение.

@Entity
@Table(name = "tb_flavor")
class Flavor {

   @OneToMany(cascade = {CascadeType.PERSIST,CascadeType.REMOVE},orphanRemoval = true)
   private Set<FlavorPositionFilling> flavors = new HashSet<FlavorPositionFilling>();

   @OneToMany(cascade = {CascadeType.PERSIST, CascadeType.REMOVE},orphanRemoval = true)
   private Set<FlavorPriceSize> priceSizes;

   // other properties and methods
}
@Entity
@Table(name = "tb_flavor_price_size")
class FlavorPriceSize {

   @EmbeddedId
   private FlavorPriceSizeEmbeddeId id;
   private float price;

   // other properties and methods
}

@Embeddable
class FlavorPriceSizeEmbeddeId implements Serializable {
   @ManyToOne(cascade = { CascadeType.ALL })
   @JoinColumn(name = "ID_FLAVOR_FK", referencedColumnName = "id_flavor")
   private Flavor flavor;

   @ManyToOne(cascade = { CascadeType.ALL })
   @JoinColumn(name = "ID_SIZE_FK", referencedColumnName = "id_size")
   private Size size;
}
@Entity
@Table(name = "tb_flabor_position_filling")
class FlaborPositionFilling {

    @EmbeddedId
    private FlaborPositionFillingEmbeddedId id;
    private Integer position;
}

@Embeddable
class FlaborPositionFillingEmbeddedId implements Serializable {
    @ManyToOne(cascade = CascadeType.REMOVE)
    @JoinColumn(name="ID_FLAVOR_FK", referencedColumnName="id_flavor")
    private Flavor sabor;

    @ManyToOne()
    @JoinColumn(name="ID_FILLING_FK", referencedColumnName="id_filling")
    private Filling filling;
}

Я много читал об обоих, но все еще не понимаю правильного использования каждого из них и их влияния на операции. Кто-нибудь может мне это объяснить? Показать видео, изображения, код ...

1 Ответ

0 голосов
/ 10 июня 2019

Предположим, что у вас есть отношение родителя -> ребенка.

Если вы установите CacadeType.REMOVE для отношения, каждый вызов EntityManager.remove для родителя также удалит дочерние элементы.

orphanRemoval = true используется для удаления детей-сирот.

Таким образом, если удалить дочерний элемент из родительской ссылки или коллекции и сохранить родительский, дочерний элемент будет удален, поскольку егобольше не привязан к родителю.

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