L'appel explicite de save()
est un peu fastidieux. Nous pouvons simplifier cela en utilisant les cascades.
<set name="children" inverse="true" cascade="all"> <key column="parent_id"/> <one-to-many class="Child"/> </set>
Simplifie le code précédent en
Parent p = (Parent) session.load(Parent.class, pid); Child c = new Child(); p.addChild(c); session.flush();
De la même manière, nous n'avons pas à itérer sur les fils lorsque nous sauvons ou effacons un Parent
. Le code suivant efface p
et tous ses fils de la base de données.
Parent p = (Parent) session.load(Parent.class, pid); session.delete(p); session.flush();
Par contre, ce code
Parent p = (Parent) session.load(Parent.class, pid); Child c = (Child) p.getChildren().iterator().next(); p.getChildren().remove(c); c.setParent(null); session.flush();
n'effacera pas c
de la base de données, il enlèvera seulement le lien vers p
(et causera une violation de contrainte NOT NULL
, dans ce cas). Vous devez explicitement utiliser delete()
sur 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();
Dans notre cas, un Child
ne peut pas vraiment exister sans son père. Si nous effacons un Child
de la collection, nous voulons vraiment qu'il soit effacé. Pour cela, nous devons utiliser cascade="all-delete-orphan"
.
<set name="children" inverse="true" cascade="all-delete-orphan"> <key column="parent_id"/> <one-to-many class="Child"/> </set>
A noter : même si le mapping de la collection spécifie inverse="true"
, les cascades sont toujours assurées par l'itération sur les éléments de la collection. Donc, si vous avez besoin qu'un objet
soit enregistré, effacé ou mis à jour par cascade, vous devez l'ajouter dans la colleciton. Il ne suffit pas d'appeler explicitement
setParent()
.