/// <summary></summary>
		public override void Execute()
		{
			// Don't need to lock the cache here, since if someone
			// else inserted the same pk first, the insert would fail
			Persister.Insert( Id, state, Instance, Session );
			Session.PostInsert( Instance );

			if ( Persister.HasCache && !Persister.IsCacheInvalidationRequired )
			{
				cacheEntry = new CacheEntry( Instance, Persister, Session );
				Persister.Cache.Insert( Id, cacheEntry );
			}
		}
		/// <summary></summary>
		public override void Execute()
		{
			if( Persister.HasCache )
			{
				_lock = Persister.Cache.Lock( Id, lastVersion );
			}
			Persister.Update( Id, fields, dirtyFields, oldFields, lastVersion, Instance, Session );
			Session.PostUpdate( Instance, updatedState, nextVersion );

			if ( Persister.HasCache )
			{
				if ( Persister.IsCacheInvalidationRequired )
				{
					Persister.Cache.Evict( Id );
				}
				else
				{
					// TODO: Inefficient if that cache is just going to ignore the updated state!
					cacheEntry = new CacheEntry( Instance, Persister, Session );
					Persister.Cache.Update( Id, cacheEntry );
				}
			}
		}
		/// <summary></summary>
		public override void Execute()
		{
			// Don't need to lock the cache here, since if someone
			// else inserted the same pk first, the insert would fail
			Persister.Insert(Id, state, Instance, Session);

			EntityEntry entry = Session.GetEntry(Instance);
			if (entry == null)
			{
				throw new AssertionFailure("possible nonthreadsafe access to session");
			}
			entry.PostInsert();

			if (Persister.HasInsertGeneratedProperties)
			{
				Persister.ProcessInsertGeneratedProperties(Id, Instance, state, Session);
				if (Persister.IsVersionPropertyGenerated)
				{
					version = Versioning.GetVersion(state, Persister);
				}
				entry.PostUpdate(Instance, state, version);
			}


			if (Persister.HasCache && !Persister.IsCacheInvalidationRequired)
			{
				cacheEntry = new CacheEntry(Instance, Persister, Session);
				CacheKey ck = new CacheKey(
					Id,
					Persister.IdentifierType,
					(string) Persister.IdentifierSpace,
					Session.Factory
					);
				Persister.Cache.Insert(ck, cacheEntry);
			}
		}
		/// <summary></summary>
		public override void Execute()
		{
			CacheKey ck = null;
			if (Persister.HasCache)
			{
				ck = new CacheKey(
					Id,
					Persister.IdentifierType,
					(string) Persister.IdentifierSpace,
					Session.Factory
					);
				_lock = Persister.Cache.Lock(ck, lastVersion);
			}
			Persister.Update(Id, state, dirtyFields, hasDirtyCollection, previousState, lastVersion, Instance, Session);
			
			EntityEntry entry = Session.GetEntry(Instance);
			if (entry == null)
			{
				throw new AssertionFailure("possible nonthreadsafe access to session");
			}

			if (entry.Status == Status.Loaded || Persister.IsVersionPropertyGenerated)
			{
				// get the updated snapshot of the entity state by cloning current state;
				// it is safe to copy in place, since by this time no-one else (should have)
				// has a reference  to the array
				TypeFactory.DeepCopy(
						state,
						Persister.PropertyTypes,
						Persister.PropertyCheckability,
						state);
				if (Persister.HasUpdateGeneratedProperties)
				{
					// this entity defines proeprty generation, so process those generated
					// values...
					Persister.ProcessUpdateGeneratedProperties(Id, Instance, state, Session);
					if (Persister.IsVersionPropertyGenerated)
					{
						nextVersion = Versioning.GetVersion(state, Persister);
					}
				}
				// have the entity entry perform post-update processing, passing it the
				// update state and the new version (if one).
				entry.PostUpdate(Instance, state, nextVersion);
			}

			if (Persister.HasCache)
			{
				if (Persister.IsCacheInvalidationRequired || entry.Status != Status.Loaded)
				{
					Persister.Cache.Evict(ck);
				}
				else
				{
					// TODO: Inefficient if that cache is just going to ignore the updated state!
					cacheEntry = new CacheEntry(Instance, Persister, Session);
					Persister.Cache.Update(ck, cacheEntry);
				}
			}
		}
		private object AssembleCacheEntry( CacheEntry entry, object id, IClassPersister persister, object optionalObject )
		{
			if( log.IsDebugEnabled )
			{
				log.Debug( "resolved object in second-level cache " + MessageHelper.InfoString( persister, id ) );
			}
			IClassPersister subclassPersister = GetClassPersister( entry.Subclass );
			object result = optionalObject != null ? optionalObject : Instantiate( subclassPersister, id );
			AddEntry( result, Status.Loading, null, id, null, LockMode.None, true, subclassPersister, false );
			AddEntity( new Key( id, persister ), result );

			IType[ ] types = subclassPersister.PropertyTypes;
			object[ ] values = entry.Assemble( result, id, subclassPersister, interceptor, this ); // intializes result by side-effect

			TypeFactory.DeepCopy( values, types, subclassPersister.PropertyUpdateability, values );
			object version = Versioning.GetVersion( values, subclassPersister );

			if( log.IsDebugEnabled )
			{
				log.Debug( "Cached Version: " + version );
			}

			AddEntry( result, Status.Loaded, values, id, version, LockMode.None, true, subclassPersister, false );
			InitializeNonLazyCollections();

			// upgrade lock if necessary;
			//Lock( result, lockMode );

			return result;
		}