Вы можете устранить разочарования явного вызова save () с помощью каскадов.
<set name="children" inverse="true" cascade="all">
<key column="parent_id"/>
<one-to-many class="Child"/>
</set>
Это упрощает приведенный выше код до:
Parent p = (Parent) session.load(Parent.class, pid);
Child c = new Child();
p.addChild(c);
session.flush();
Аналогично, нам не нужно перебирать дочерние элементы при сохранении или удалении Parent
.Следующее удаляет p
и все его дочерние элементы из базы данных.
Parent p = (Parent) session.load(Parent.class, pid);
session.delete(p);
session.flush();
Однако следующий код:
Parent p = (Parent) session.load(Parent.class, pid);
Child c = (Child) p.getChildren().iterator().next();
p.getChildren().remove(c);
c.setParent(null);
session.flush();
не удалит c
из базы данных.В этом случае будет удалена только ссылка на p
, что приведет к нарушению ограничения NOT NULL
.Вам необходимо явно delete()
Child
.
Parent p = (Parent) session.load(Parent.class, pid);
Child c = (Child) p.getChildren().iterator().next();
p.getChildren().remove(c);
session.delete(c);
session.flush();
В нашем случае Child
не может существовать без своего родителя.Поэтому, если мы удалим Child
из коллекции, мы хотим, чтобы он был удален.Чтобы сделать это, мы должны использовать cascade="all-delete-orphan"
.
<set name="children" inverse="true" cascade="all-delete-orphan">
<key column="parent_id"/>
<one-to-many class="Child"/>
</set>
Даже при том, что в отображении коллекции указано inverse="true"
, каскады по-прежнему обрабатываются путем итерации элементов коллекции.Если вам нужно, чтобы объект был сохранен, удален или обновлен каскадом, вы должны добавить его в коллекцию.Недостаточно просто позвонить setParent()
.