class Foo{
Set<Bar> bars;
}
class Bar{
Foo parent;
String localIdentifier;
}
Avec cette mise en correspondance (désolé, pas d'annotations, je suis vieux jeu):
<class name="Foo">
...
<set name="bars" cascade="all-delete-orphan" lazy="false" inverse="true">
<key>...</key>
<one-to-many class="Bar"/>
</set>
</class>
<class name="Bar">
...
<property name="localIdentifier" column="local_identifier"/>
<many-to-one name="parent" column="parent_id" />
</class>
J'ai aussi une contrainte unique sur 2 colonnes: local_identifier
et parent_id
(pas une contrainte unique sur chacun, mais une seule contrainte unique, contenant à la fois, par exemple, pas sont autorisés 2 lignes avec le même parent et même LocalIdentifier)
alter table bar add constraint unique_bar unique (parent_id, local_identifier)
Et ce code qui les utilise:
//foo is persistent, foo id = 1
Bars bars = foo.getBars();
bars.clear(); // bars contained 1 item [parent_id = 1, local_identifier = "a"]
Bar newBar = new Bar();
newBar.setParent(foo);
newBar.setLocalIdentifier("a");
bars.add(newBar);
Maintenant, pour une raison quelconque, Hibernate n'exécute pas les choses dans l'ordre où ils ont été appelés. Il n'exécute pas clear()
(supprimer) avant la add()
(insert), mais vice-versa, il essaie d'abord d'insérer, d'obtenir un ConstraintViolationException
Je sais que l'ajout d'un peu session.flush()
après bars.clear();
, pourrait résoudre ce problème, mais dans ce cas , Je n'ai pas accès à la session d'une manière non laide.
Est-ce que le flush est la seule solution? ou existe-t-il une version Hibernate qui respecte l'ordre des actions?
Mise à jour: Par ailleurs, la collection déréférencement entraînera une HibernateException de https://www.hibernate.org/117.html#A3:
Je me HibernateException: Ne pas déréférencer une collection avec cascade = "all-delete -orphan " Ce se produira si vous chargez un objet avec une collection cascade =" all-delete-orphan " , puis supprimez la référence de la collection. Ne pas remplacer cette collection, utilisez clear() de sorte que l'algorithme de suppression orphelin peut détecter votre changement.
Je pense que flushing est la seule option ici – ruchirhhi
Relative [Hibernate Forum topic] (https://forum.hibernate.org/viewtopic.php?t=934483). –