FileDocCategorySizeDatePackage
AbstractLockUpgradeEventListener.javaAPI DocHibernate 3.2.53243Thu Feb 23 10:32:48 GMT 2006org.hibernate.event.def

AbstractLockUpgradeEventListener

public class AbstractLockUpgradeEventListener extends AbstractReassociateEventListener
A convenience base class for listeners that respond to requests to perform a pessimistic lock upgrade on an entity.
author
Gavin King

Fields Summary
private static final Log
log
Constructors Summary
Methods Summary
protected voidupgradeLock(java.lang.Object object, org.hibernate.engine.EntityEntry entry, org.hibernate.LockMode requestedLockMode, org.hibernate.engine.SessionImplementor source)
Performs a pessimistic lock upgrade on a given entity, if needed.

param
object The entity for which to upgrade the lock.
param
entry The entity's EntityEntry instance.
param
requestedLockMode The lock mode being requested for locking.
param
source The session which is the source of the event being processed.
throws
HibernateException


	                                                   	 
	         
	  

		if ( requestedLockMode.greaterThan( entry.getLockMode() ) ) {
			// The user requested a "greater" (i.e. more restrictive) form of
			// pessimistic lock

			if ( entry.getStatus() != Status.MANAGED ) {
				throw new ObjectDeletedException(
						"attempted to lock a deleted instance",
						entry.getId(),
						entry.getPersister().getEntityName()
				);
			}

			final EntityPersister persister = entry.getPersister();

			if ( log.isTraceEnabled() )
				log.trace(
						"locking " +
						MessageHelper.infoString( persister, entry.getId(), source.getFactory() ) +
						" in mode: " +
						requestedLockMode
				);

			final CacheConcurrencyStrategy.SoftLock lock;
			final CacheKey ck;
			if ( persister.hasCache() ) {
				ck = new CacheKey( 
						entry.getId(), 
						persister.getIdentifierType(), 
						persister.getRootEntityName(), 
						source.getEntityMode(), 
						source.getFactory() 
				);
				lock = persister.getCache().lock( ck, entry.getVersion() );
			}
			else {
				ck = null;
				lock = null;
			}
			
			try {
				if ( persister.isVersioned() && requestedLockMode == LockMode.FORCE ) {
					// todo : should we check the current isolation mode explicitly?
					Object nextVersion = persister.forceVersionIncrement(
							entry.getId(), entry.getVersion(), source
					);
					entry.forceLocked( object, nextVersion );
				}
				else {
					persister.lock( entry.getId(), entry.getVersion(), object, requestedLockMode, source );
				}
				entry.setLockMode(requestedLockMode);
			}
			finally {
				// the database now holds a lock + the object is flushed from the cache,
				// so release the soft lock
				if ( persister.hasCache() ) {
					persister.getCache().release(ck, lock );
				}
			}

		}