I have a complex object graph in which the root entity has a list of all VersionRecords (representing all the updates it went through during its life). However, some of these VersionRecord instances are shared with objects in the object tree so each of them points to its current VersionRecord, which is always in the root entity list as well.
So, stripped down to its minimum, I have:
Object A holds a list of VersionRecord and an Object B containing only a single instance in our case
Object B points to a VersionRecord too (an instance shared with A)
Now, when we delete the root (A): Hibernate deletes the shared VersionRecord in its list as part of the cascade delete on Object A, but then, when cascade deleting B, it sees the shared VersionRecord has been deleted (now transient) and nullifies the reference to that instance from B's property, which then fails to pass the checks for nullability since that property is NOT nullable in B.
from DefaultDeleteEventListener.deleteEntity method:
Code:
...
// MyComment: this nullifies every property pointing to deleted (now transient) instances (for ManyToOne only?)
new ForeignKeys.Nullifier( entity, true, false, session ).nullifyTransientReferences( entityEntry.getDeletedState(), propTypes );
// MyComment: then this checks not-null constraints from the metadata against nulled properties! Why on delete?
new Nullability( session ).checkNullability( entityEntry.getDeletedState(), persister, true );
...
Why nullify references to transient instances (just deleted or not) from an object that is going to be deleted?