package org.hibernate.action.internal;
import java.io.Serializable;
import org.hibernate.action.spi.AfterTransactionCompletionProcess;
import org.hibernate.action.spi.BeforeTransactionCompletionProcess;
import org.hibernate.action.spi.Executable;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.spi.CacheKey;
import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.SessionImplementor;
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.collection.CollectionPersister;
import org.hibernate.pretty.MessageHelper;
public abstract class CollectionAction implements Executable, Serializable, Comparable {
private transient CollectionPersister persister;
private transient SessionImplementor session;
private final PersistentCollection collection;
private final Serializable key;
private final String collectionRole;
protected CollectionAction(
final CollectionPersister persister,
final PersistentCollection collection,
final Serializable key,
final SessionImplementor session) {
this.persister = persister;
this.session = session;
this.key = key;
this.collectionRole = persister.getRole();
this.collection = collection;
}
protected PersistentCollection getCollection() {
return collection;
}
public void afterDeserialize(SessionImplementor 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().getCollectionPersister( collectionRole );
}
}
@Override
public final void beforeExecutions() throws CacheException {
if ( persister.hasCache() ) {
final CacheKey ck = session.generateCacheKey(
key,
persister.getKeyType(),
persister.getRole()
);
final SoftLock lock = persister.getCacheAccessStrategy().lockItem( ck, null );
afterTransactionProcess = new CacheCleanupProcess( key, persister, lock );
}
}
@Override
public BeforeTransactionCompletionProcess getBeforeTransactionCompletionProcess() {
return null;
}
private AfterTransactionCompletionProcess afterTransactionProcess;
@Override
public AfterTransactionCompletionProcess getAfterTransactionCompletionProcess() {
return afterTransactionProcess;
}
@Override
public Serializable[] getPropertySpaces() {
return persister.getCollectionSpaces();
}
protected final CollectionPersister getPersister() {
return persister;
}
protected final Serializable getKey() {
Serializable finalKey = key;
if ( key instanceof DelayedPostInsertIdentifier ) {
finalKey = session.getPersistenceContext().getEntry( collection.getOwner() ).getId();
if ( finalKey == key ) {
}
}
return finalKey;
}
protected final SessionImplementor getSession() {
return session;
}
protected final void evict() throws CacheException {
if ( persister.hasCache() ) {
final CacheKey ck = session.generateCacheKey(
key,
persister.getKeyType(),
persister.getRole()
);
persister.getCacheAccessStrategy().remove( ck );
}
}
@Override
public String toString() {
return StringHelper.unqualify( getClass().getName() ) + MessageHelper.infoString( collectionRole, key );
}
@Override
public int compareTo(Object other) {
final CollectionAction action = (CollectionAction) other;
final int roleComparison = collectionRole.compareTo( action.collectionRole );
if ( roleComparison != 0 ) {
return roleComparison;
}
else {
return persister.getKeyType().compare( key, action.key );
}
}
private static class CacheCleanupProcess implements AfterTransactionCompletionProcess {
private final Serializable key;
private final CollectionPersister persister;
private final SoftLock lock;
private CacheCleanupProcess(Serializable key, CollectionPersister persister, SoftLock lock) {
this.key = key;
this.persister = persister;
this.lock = lock;
}
@Override
public void doAfterTransactionCompletion(boolean success, SessionImplementor session) {
final CacheKey ck = session.generateCacheKey(
key,
persister.getKeyType(),
persister.getRole()
);
persister.getCacheAccessStrategy().unlockItem( ck, lock );
}
}
protected <T> EventListenerGroup<T> listenerGroup(EventType<T> eventType) {
return getSession()
.getFactory()
.getServiceRegistry()
.getService( EventListenerRegistry.class )
.getEventListenerGroup( eventType );
}
protected EventSource eventSource() {
return (EventSource) getSession();
}
}