Настройки каскадов в JPA и нарушение внешнего ключа в спящем режиме

У меня есть буксирные классы:

  1. родитель
  2. ребенок

В базе данных дочерней таблицы есть столбец ParentId -> типичное отношение One (Parent) -> Many (Children)

Теперь я создаю две сущности, и они

public class Parent
{
    @OneToMany(mappedBy="Parent", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    public Set<Child> getChildern()
    {
      ...
    }
}

public class Child
{
   @ManyToOne(fetch = FetchType.EAGER, cascade=CascadeType.ALL)
   @JoinColumn(name="ParentId")
   public Parent getParent()
   { ... }
}

Теперь у меня есть два сценария:

  1. Родитель удаляется -> что должно произойти?
  2. Ребенок удаляется -> что должно произойти?

Бонусные вопросы:

  1. Мне всегда нужно создавать обе части ключа OneToMany и ManyToOne, или я могу просто иметь ManyToOne и не заботиться о родителе, где у меня есть дети?
  2. Что может привести к тому, что спящий режим выдаст мне сообщение о нарушении ограничения внешнего ключа для родителя, у которого нет дочерних элементов?

1 ответ

Решение

Прежде всего, я удивлен, что этот код работает вообще. IMO mappedBy="Parent" должно быть на самом деле mappedBy="parent" (обратите внимание на строчную букву 'p'), потому что родительское свойство Child класс называется parent и не Parent,

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

Ответы на ваши вопросы зависят от того, что именно вы подразумеваете под "удалить". Я предполагаю, что вы имеете в виду "удален через менеджер постоянства".

НО только на тот случай, если вы ожидаете / хотите, чтобы ребенок был удален провайдером JPA, если вы это сделаете parent.getChildren().remove(x) тогда вам нужно установить orphanRemoval = "true" на OneToMany,

Вопрос 1

Родитель и все дети удалены. Это частый случай.

вопрос 2

Родитель и все дети удалены. Это довольно странный вариант использования. Обычно каскадное удаление применяется только в отношении "один ко многим".

Бонус 1

Все отношения в Java и JPA являются однонаправленными, в том случае, если исходный объект ссылается на целевой объект, нет никакой гарантии, что целевой объект также имеет отношение к исходному объекту.

из превосходной вики книги о персистенции Java.

Бонус 2

Не знаю. Это ConstraintViolationException исходя из базовой базы данных? Или по-другому, как выглядит DDL для двух таблиц? Это было сгенерировано Hibernate?

Другие вопросы по тегам