package org.hibernate.action.internal;
import java.io.Serializable;
import org.hibernate.AssertionFailure;
import org.hibernate.action.spi.AfterTransactionCompletionProcess;
import org.hibernate.action.spi.BeforeTransactionCompletionProcess;
import org.hibernate.action.spi.Executable;
import org.hibernate.engine.spi.EntityEntry;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.event.service.spi.EventListenerGroup;
import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.event.spi.EventSource;
import org.hibernate.event.spi.EventType;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.pretty.MessageHelper;
import org.jboss.logging.Logger;
public abstract class EntityAction
implements Executable, Serializable, Comparable, AfterTransactionCompletionProcess {
private static final Logger LOG = Logger.getLogger(EntityAction.class);
private final String entityName;
private final Serializable id;
private transient Object instance;
private transient SharedSessionContractImplementor session;
private transient EntityPersister persister;
private transient boolean veto;
protected EntityAction(SharedSessionContractImplementor session, Serializable id, Object instance, EntityPersister persister) {
this.entityName = persister.getEntityName();
this.id = id;
this.instance = instance;
this.session = session;
this.persister = persister;
}
public boolean isVeto() {
return veto;
}
public void setVeto(boolean veto) {
this.veto = veto;
}
@Override
public BeforeTransactionCompletionProcess getBeforeTransactionCompletionProcess() {
return null;
}
@Override
public AfterTransactionCompletionProcess getAfterTransactionCompletionProcess() {
return needsAfterTransactionCompletion()
? this
: null;
}
protected abstract boolean hasPostCommitEventListeners();
protected boolean needsAfterTransactionCompletion() {
return persister.canWriteToCache() || hasPostCommitEventListeners();
}
public String getEntityName() {
return entityName;
}
public final Serializable getId() {
if ( id instanceof DelayedPostInsertIdentifier ) {
final EntityEntry entry = session.getPersistenceContext().getEntry( instance );
if ( entry == null ) {
if ( LOG.isDebugEnabled() ) {
LOG.debugf(
"Skipping action - the persistence context does not contain any entry for the entity [%s]. This may occur if an entity is created and then deleted in the same transaction/flush.",
instance
);
}
return null;
}
final Serializable eeId = entry.getId();
return eeId instanceof DelayedPostInsertIdentifier ? null : eeId;
}
return id;
}
public final DelayedPostInsertIdentifier getDelayedId() {
return DelayedPostInsertIdentifier.class.isInstance( id )
? DelayedPostInsertIdentifier.class.cast( id )
: null;
}
public final Object getInstance() {
return instance;
}
public final SharedSessionContractImplementor getSession() {
return session;
}
public final EntityPersister getPersister() {
return persister;
}
@Override
public final Serializable[] getPropertySpaces() {
return persister.getPropertySpaces();
}
@Override
public void beforeExecutions() {
throw new AssertionFailure( "beforeExecutions() called for non-collection action" );
}
@Override
public String toString() {
return StringHelper.unqualify( getClass().getName() ) + MessageHelper.infoString( entityName, id );
}
@Override
public int compareTo(Object other) {
final EntityAction action = (EntityAction) other;
final int roleComparison = entityName.compareTo( action.entityName );
if ( roleComparison != 0 ) {
return roleComparison;
}
else {
return persister.getIdentifierType().compare( id, action.id );
}
}
@Override
public void afterDeserialize(SharedSessionContractImplementor session) {
if ( this.session != null || this.persister != null ) {
throw new IllegalStateException( "already attached to a session." );
}
if ( session != null ) {
this.session = session;
this.persister = session.getFactory().getMetamodel().entityPersister( entityName );
this.instance = session.getPersistenceContext().getEntity( session.generateEntityKey( id, persister ) );
}
}
protected <T> EventListenerGroup<T> listenerGroup(EventType<T> eventType) {
return getSession()
.getFactory()
.getServiceRegistry()
.getService( EventListenerRegistry.class )
.getEventListenerGroup( eventType );
}
protected EventSource eventSource() {
return (EventSource) getSession();
}
}