support for deferred constraint (in delete action)

Description

Currently Hibernate does not have support for deferred constraints.
In good design usage of deferred constraints can be avoided, but the module which we work on, recieves the data/records/transactions
from other system - and it doesn't keep the proper order of the records in the transaction.
(the problem is also described under: http://forum.hibernate.org/viewtopic.php?t=965663)

Scenario:
Object A has reference to B (unidirectional).

'Normal' delete scenario:
delete A
delete B
The proper order of deleting and all is ok.

Problematic scenario is (one transaction):
delete B
delete A

Of course after first delete (B), database throws an 'foreign' key constraint.

It is easily solvable using deferred contraints - on DB level (Informix/Oracle, etc).

But now Hibernate does a check and throws 'not-null property references a null or transient value'
(in this case B is transient during delete of A).

Looks to me that Hibernate checks to strictly.
Lets analyze this code:
(DefaultDeleteEventListener.java)

protected final void deleteEntity(
final EventSource session,
final Object entity,
final EntityEntry entityEntry,
final boolean isCascadeDeleteEnabled,
final EntityPersister persister)
throws HibernateException {
....

session.getInterceptor().onDelete(
entity,
entityEntry.getId(),
deletedState,
persister.getPropertyNames(),
propTypes
);

// before any callbacks, etc, so subdeletions see that this deletion happened first
persistenceContext.setEntryStatus(entityEntry, Status.DELETED);
EntityKey key = new EntityKey( entityEntry.getId(), persister, session.getEntityMode() );

cascadeBeforeDelete(session, persister, entity, entityEntry);

new ForeignKeys.Nullifier(entity, true, false, session)
.nullifyTransientReferences( entityEntry.getDeletedState(), propTypes );
new Nullability(session).checkNullability( entityEntry.getDeletedState(), persister, true );
...

The last three lines does the check which throws an error.
I don't see the reason of this check here - object is just being deleted, so it doesn't matter that some of its
properties is null or transient.
After commenting the code:
// new ForeignKeys.Nullifier(entity, true, false, session)
// .nullifyTransientReferences( entityEntry.getDeletedState(), propTypes );
// new Nullability(session).checkNullability( entityEntry.getDeletedState(), persister, true );
the scenario with deferred constraints works properly. Also any side effects wasn't observed.
If it isn't fully correct change, let me know how to improve it.

Activity

Show:

Steve Ebersole August 8, 2024 at 2:26 PM

Very few databases actually support deferrable constraints. In fact, PostgreSQL and Oracle are the only 2 I know of. So it does not seem worth the investment to add explicit support for them.

I'd suggest trying `@ForeignKey(..., options="deferrable")` to see if that works for you.

Rejected

Details

Assignee

Reporter

Components

Priority

Created November 17, 2006 at 11:21 AM
Updated December 3, 2024 at 9:06 AM
Resolved August 8, 2024 at 2:26 PM