I have these entities
class Foo{
Set<Bar> bars;
}
class Bar{
Foo parent;
String localIdentifier;
}
With this mapping (sorry, no annotations, I'm old fasioned):
<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>
I also have a unique constraint on 2 columns: local_identifier
and parent_id
(not a unique constrain on each, but a single unique constrain containing both, e.g. no 2 rows with the same parent and same localIdentifier are allowed)
alter table bar add constraint unique_bar unique (parent_id, local_identifier)
And this code that uses them:
//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);
Now, for some reason, Hibernate doesn't execute things in the order they were called. It doesn't execute the clear()
(delete) before the add()
(insert) but vice versa, it first tries to insert, getting a ConstraintViolationException
I know adding a little session.flush()
after bars.clear();
, couldfix this, but in this case, I have no access to the session in a non ugly way.
So is flush is the only solution? or is there a Hibernate version that respects the order of actions?
Update: By the way, dereferencing the collection will result in a HibernateException from https://www.hibernate.org/117.html#A3:
I get HibernateException: Don't dereference a collection with cascade="all-delete-orphan" This will happen if you load an object with a cascade="all-delete-orphan" collection and then remove the reference to the collection. Don't replace this collection, use clear() so the orphan-deletion algorithm can detect your change.