Supposons que nous ayons chargé un Parent
dans une Session
, que nous l'ayons ensuite modifié et que voulions persiter ces modifications dans une nouvelle session en appelant update()
. Le Parent
contiendra une collection de fils et, puisque la cascade est activée, Hibernate a besoin de savoir quels fils viennent d'être
instanciés et quels fils proviennent de la base de données. Supposons aussi que Parent
et Child
ont tous deux des identifiants du type Long
. Hibernate utilisera la propriété de l'identifiant et la propriété de la version/horodatage pour déterminer quels fils sont
nouveaux (vous pouvez aussi utiliser la propriété version ou timestamp, voir ???). Dans Hibernate3, il n'est plus nécessaire de spécifier une unsaved-value
explicitement.
Le code suivant mettra à jour parent
et child
et insérera newChild
.
//parent and child were both loaded in a previous session parent.addChild(child); Child newChild = new Child(); parent.addChild(newChild); session.update(parent); session.flush();
Ceci est très bien pour des identifiants générés, mais qu'en est-il des identifiants assignés et des identifiants composés ? C'est plus difficile, puisqu'Hibernate ne peut pas utiliser la propriété de l'identifiant pour distinguer un objet nouvellement instancié (avec un identifiant assigné par l'utilisateur) d'un objet chargé dans une session précédente. Dans ce cas, Hibernate utilisera soit la propriété de version ou d'horodatage, soit effectuera vraiment une requête au cache de second niveau, soit, dans le pire des cas, à la base de données, pour voir si la ligne existe.