Настройки каскадов в JPA и нарушение внешнего ключа в спящем режиме
У меня есть буксирные классы:
- родитель
- ребенок
В базе данных дочерней таблицы есть столбец 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()
{ ... }
}
Теперь у меня есть два сценария:
- Родитель удаляется -> что должно произойти?
- Ребенок удаляется -> что должно произойти?
Бонусные вопросы:
- Мне всегда нужно создавать обе части ключа OneToMany и ManyToOne, или я могу просто иметь ManyToOne и не заботиться о родителе, где у меня есть дети?
- Что может привести к тому, что спящий режим выдаст мне сообщение о нарушении ограничения внешнего ключа для родителя, у которого нет дочерних элементов?
1 ответ
Прежде всего, я удивлен, что этот код работает вообще. IMO mappedBy="Parent"
должно быть на самом деле mappedBy="parent"
(обратите внимание на строчную букву 'p'), потому что родительское свойство Child
класс называется parent
и не Parent
,
Во-вторых, я предлагаю вам размещать аннотации в свойствах, а не в методах доступа. Я считаю, что это делает весь код
- более читабельный
- легче поддерживать, потому что Lombok может добавить закулис / сеттеры за кулисы
Ответы на ваши вопросы зависят от того, что именно вы подразумеваете под "удалить". Я предполагаю, что вы имеете в виду "удален через менеджер постоянства".
НО только на тот случай, если вы ожидаете / хотите, чтобы ребенок был удален провайдером JPA, если вы это сделаете parent.getChildren().remove(x)
тогда вам нужно установить orphanRemoval = "true"
на OneToMany
,
Вопрос 1
Родитель и все дети удалены. Это частый случай.
вопрос 2
Родитель и все дети удалены. Это довольно странный вариант использования. Обычно каскадное удаление применяется только в отношении "один ко многим".
Бонус 1
Все отношения в Java и JPA являются однонаправленными, в том случае, если исходный объект ссылается на целевой объект, нет никакой гарантии, что целевой объект также имеет отношение к исходному объекту.
из превосходной вики книги о персистенции Java.
Бонус 2
Не знаю. Это ConstraintViolationException
исходя из базовой базы данных? Или по-другому, как выглядит DDL для двух таблиц? Это было сгенерировано Hibernate?