DefaultDeleteEventListenerpublic class DefaultDeleteEventListener extends Object implements org.hibernate.event.DeleteEventListenerDefines the default delete event listener used by hibernate for deleting entities
from the datastore in response to generated delete events. |
Fields Summary |
---|
private static final Log | log |
Methods Summary |
---|
protected void | cascadeAfterDelete(org.hibernate.event.EventSource session, org.hibernate.persister.entity.EntityPersister persister, java.lang.Object entity, java.util.Set transientEntities)
CacheMode cacheMode = session.getCacheMode();
session.setCacheMode( CacheMode.GET );
session.getPersistenceContext().incrementCascadeLevel();
try {
// cascade-delete to many-to-one AFTER the parent was deleted
new Cascade( CascadingAction.DELETE, Cascade.BEFORE_INSERT_AFTER_DELETE, session )
.cascade( persister, entity, transientEntities );
}
finally {
session.getPersistenceContext().decrementCascadeLevel();
session.setCacheMode( cacheMode );
}
| protected void | cascadeBeforeDelete(org.hibernate.event.EventSource session, org.hibernate.persister.entity.EntityPersister persister, java.lang.Object entity, org.hibernate.engine.EntityEntry entityEntry, java.util.Set transientEntities)
CacheMode cacheMode = session.getCacheMode();
session.setCacheMode( CacheMode.GET );
session.getPersistenceContext().incrementCascadeLevel();
try {
// cascade-delete to collections BEFORE the collection owner is deleted
new Cascade( CascadingAction.DELETE, Cascade.AFTER_INSERT_BEFORE_DELETE, session )
.cascade( persister, entity, transientEntities );
}
finally {
session.getPersistenceContext().decrementCascadeLevel();
session.setCacheMode( cacheMode );
}
| private java.lang.Object[] | createDeletedState(org.hibernate.persister.entity.EntityPersister persister, java.lang.Object[] currentState, org.hibernate.event.EventSource session)
Type[] propTypes = persister.getPropertyTypes();
final Object[] deletedState = new Object[propTypes.length];
// TypeFactory.deepCopy( currentState, propTypes, persister.getPropertyUpdateability(), deletedState, session );
boolean[] copyability = new boolean[propTypes.length];
java.util.Arrays.fill( copyability, true );
TypeFactory.deepCopy( currentState, propTypes, copyability, deletedState, session );
return deletedState;
| protected final void | deleteEntity(org.hibernate.event.EventSource session, java.lang.Object entity, org.hibernate.engine.EntityEntry entityEntry, boolean isCascadeDeleteEnabled, org.hibernate.persister.entity.EntityPersister persister, java.util.Set transientEntities)Perform the entity deletion. Well, as with most operations, does not
really perform it; just schedules an action/execution with the
{@link org.hibernate.engine.ActionQueue} for execution during flush.
if ( log.isTraceEnabled() ) {
log.trace(
"deleting " +
MessageHelper.infoString( persister, entityEntry.getId(), session.getFactory() )
);
}
final PersistenceContext persistenceContext = session.getPersistenceContext();
final Type[] propTypes = persister.getPropertyTypes();
final Object version = entityEntry.getVersion();
final Object[] currentState;
if ( entityEntry.getLoadedState() == null ) { //ie. the entity came in from update()
currentState = persister.getPropertyValues( entity, session.getEntityMode() );
}
else {
currentState = entityEntry.getLoadedState();
}
final Object[] deletedState = createDeletedState( persister, currentState, session );
entityEntry.setDeletedState( deletedState );
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, transientEntities );
new ForeignKeys.Nullifier( entity, true, false, session )
.nullifyTransientReferences( entityEntry.getDeletedState(), propTypes );
new Nullability( session ).checkNullability( entityEntry.getDeletedState(), persister, true );
persistenceContext.getNullifiableEntityKeys().add( key );
// Ensures that containing deletions happen before sub-deletions
session.getActionQueue().addAction(
new EntityDeleteAction(
entityEntry.getId(),
deletedState,
version,
entity,
persister,
isCascadeDeleteEnabled,
session
)
);
cascadeAfterDelete( session, persister, entity, transientEntities );
// the entry will be removed after the flush, and will no longer
// override the stale snapshot
// This is now handled by removeEntity() in EntityDeleteAction
//persistenceContext.removeDatabaseSnapshot(key);
| protected void | deleteTransientEntity(org.hibernate.event.EventSource session, java.lang.Object entity, boolean cascadeDeleteEnabled, org.hibernate.persister.entity.EntityPersister persister, java.util.Set transientEntities)We encountered a delete request on a transient instance.
This is a deviation from historical Hibernate (pre-3.2) behavior to
align with the JPA spec, which states that transient entities can be
passed to remove operation in which case cascades still need to be
performed.
log.info( "handling transient entity in delete processing" );
if ( transientEntities.contains( entity ) ) {
log.trace( "already handled transient entity; skipping" );
return;
}
transientEntities.add( entity );
cascadeBeforeDelete( session, persister, entity, null, transientEntities );
cascadeAfterDelete( session, persister, entity, transientEntities );
| protected boolean | invokeDeleteLifecycle(org.hibernate.event.EventSource session, java.lang.Object entity, org.hibernate.persister.entity.EntityPersister persister)
if ( persister.implementsLifecycle( session.getEntityMode() ) ) {
log.debug( "calling onDelete()" );
if ( ( ( Lifecycle ) entity ).onDelete( session ) ) {
log.debug( "deletion vetoed by onDelete()" );
return true;
}
}
return false;
| public void | onDelete(org.hibernate.event.DeleteEvent event)Handle the given delete event.
onDelete( event, new IdentitySet() );
| public void | onDelete(org.hibernate.event.DeleteEvent event, java.util.Set transientEntities)Handle the given delete event. This is the cascaded form.
final EventSource source = event.getSession();
final PersistenceContext persistenceContext = source.getPersistenceContext();
Object entity = persistenceContext.unproxyAndReassociate( event.getObject() );
EntityEntry entityEntry = persistenceContext.getEntry( entity );
final EntityPersister persister;
final Serializable id;
final Object version;
if ( entityEntry == null ) {
log.trace( "entity was not persistent in delete processing" );
persister = source.getEntityPersister( event.getEntityName(), entity );
if ( ForeignKeys.isTransient( persister.getEntityName(), entity, null, source ) ) {
deleteTransientEntity( source, entity, event.isCascadeDeleteEnabled(), persister, transientEntities );
// EARLY EXIT!!!
return;
}
else {
performDetachedEntityDeletionCheck( event );
}
id = persister.getIdentifier( entity, source.getEntityMode() );
if ( id == null ) {
throw new TransientObjectException(
"the detached instance passed to delete() had a null identifier"
);
}
EntityKey key = new EntityKey( id, persister, source.getEntityMode() );
persistenceContext.checkUniqueness( key, entity );
new OnUpdateVisitor( source, id, entity ).process( entity, persister );
version = persister.getVersion( entity, source.getEntityMode() );
entityEntry = persistenceContext.addEntity(
entity,
Status.MANAGED,
persister.getPropertyValues( entity, source.getEntityMode() ),
key,
version,
LockMode.NONE,
true,
persister,
false,
false
);
}
else {
log.trace( "deleting a persistent instance" );
if ( entityEntry.getStatus() == Status.DELETED || entityEntry.getStatus() == Status.GONE ) {
log.trace( "object was already deleted" );
return;
}
persister = entityEntry.getPersister();
id = entityEntry.getId();
version = entityEntry.getVersion();
}
/*if ( !persister.isMutable() ) {
throw new HibernateException(
"attempted to delete an object of immutable class: " +
MessageHelper.infoString(persister)
);
}*/
if ( invokeDeleteLifecycle( source, entity, persister ) ) {
return;
}
deleteEntity( source, entity, entityEntry, event.isCascadeDeleteEnabled(), persister, transientEntities );
if ( source.getFactory().getSettings().isIdentifierRollbackEnabled() ) {
persister.resetIdentifier( entity, id, version, source.getEntityMode() );
}
| protected void | performDetachedEntityDeletionCheck(org.hibernate.event.DeleteEvent event)Called when we have recognized an attempt to delete a detached entity.
This is perfectly valid in Hibernate usage; JPA, however, forbids this.
Thus, this is a hook for HEM to affect this behavior.
// ok in normal Hibernate usage to delete a detached entity; JPA however
// forbids it, thus this is a hook for HEM to affect this behavior
|
|