⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 defaultloadeventlistener.cs

📁 NHibernate NET开发者所需的
💻 CS
📖 第 1 页 / 共 2 页
字号:
using System;
using log4net;
using NHibernate.Cache;
using NHibernate.Cache.Entry;
using NHibernate.Engine;
using NHibernate.Impl;
using NHibernate.Persister.Entity;
using NHibernate.Proxy;
using NHibernate.Type;

namespace NHibernate.Event.Default
{
	/// <summary> 
	/// Defines the default load event listeners used by hibernate for loading entities
	/// in response to generated load events.
	/// </summary>
	[Serializable]
	public class DefaultLoadEventListener : AbstractLockUpgradeEventListener, ILoadEventListener
	{
		private static readonly ILog log = LogManager.GetLogger(typeof(DefaultLoadEventListener));
		public static readonly object RemovedEntityMarker = new object();
		public static readonly object InconsistentRTNClassMarker= new object();
		public static readonly LockMode DefaultLockMode = LockMode.None;

		public virtual void OnLoad(LoadEvent @event, LoadType loadType)
		{
			ISessionImplementor source = @event.Session;

			IEntityPersister persister;
			if (@event.InstanceToLoad != null)
			{
				persister = source.GetEntityPersister(@event.InstanceToLoad); //the load() which takes an entity does not pass an entityName
				@event.EntityClassName = @event.InstanceToLoad.GetType().FullName;
			}
			else
			{
				persister = source.Factory.GetEntityPersister(@event.EntityClassName);
			}

			if (persister == null)
			{
				throw new HibernateException("Unable to locate persister: " + @event.EntityClassName);
			}

			if (persister.IdentifierType.IsComponentType)
			{
				// skip this check for composite-ids relating to dom4j entity-mode;
				// alternatively, we could add a check to make sure the incoming id value is
				// an instance of Element...
			}
			else
			{
				System.Type idClass = persister.IdentifierType.ReturnedClass;
				if (idClass != null && !idClass.IsInstanceOfType(@event.EntityId))
				{
					throw new TypeMismatchException("Provided id of the wrong type. Expected: " + idClass + ", got " + @event.EntityId.GetType());
				}
			}

			EntityKey keyToLoad = new EntityKey(@event.EntityId, persister, source.EntityMode);
			try
			{
				if (loadType.IsNakedEntityReturned)
				{
					//do not return a proxy!
					//(this option indicates we are initializing a proxy)
					@event.Result = Load(@event, persister, keyToLoad, loadType);
				}
				else
				{
					//return a proxy if appropriate
					if (@event.LockMode == LockMode.None)
					{
						@event.Result = ProxyOrLoad(@event, persister, keyToLoad, loadType);
					}
					else
					{
						@event.Result = LockAndLoad(@event, persister, keyToLoad, loadType, source);
					}
				}
			}
			catch (HibernateException e)
			{
				log.Info("Error performing load command", e);
				throw;
			}
		}

		/// <summary> Perfoms the load of an entity. </summary>
		/// <returns> The loaded entity. </returns>
		protected virtual object Load(LoadEvent @event, IEntityPersister persister, EntityKey keyToLoad, LoadType options)
		{
			if (@event.InstanceToLoad != null)
			{
				if (@event.Session.PersistenceContext.GetEntry(@event.InstanceToLoad) != null)
				{
					throw new PersistentObjectException("attempted to load into an instance that was already associated with the session: " + MessageHelper.InfoString(persister, @event.EntityId, @event.Session.Factory));
				}
				persister.SetIdentifier(@event.InstanceToLoad, @event.EntityId, @event.Session.EntityMode);
			}

			object entity = DoLoad(@event, persister, keyToLoad, options);

			bool isOptionalInstance = @event.InstanceToLoad != null;

			if (!options.IsAllowNulls || isOptionalInstance)
			{
				if (entity == null)
				{
					@event.Session.Factory.EntityNotFoundDelegate.HandleEntityNotFound(@event.EntityClassName, @event.EntityId);
				}
			}

			if (isOptionalInstance && entity != @event.InstanceToLoad)
			{
				throw new NonUniqueObjectException(@event.EntityId, @event.EntityClassName);
			}

			return entity;
		}

		/// <summary> 
		/// Based on configured options, will either return a pre-existing proxy,
		/// generate a new proxy, or perform an actual load. 
		/// </summary>
		/// <returns> The result of the proxy/load operation.</returns>
		protected virtual object ProxyOrLoad(LoadEvent @event, IEntityPersister persister, EntityKey keyToLoad, LoadType options)
		{
			if (log.IsDebugEnabled)
			{
				log.Debug("loading entity: " + MessageHelper.InfoString(persister, @event.EntityId, @event.Session.Factory));
			}

			if (!persister.HasProxy)
			{
				// this class has no proxies (so do a shortcut)
				return Load(@event, persister, keyToLoad, options);
			}
			else
			{
				IPersistenceContext persistenceContext = @event.Session.PersistenceContext;

				// look for a proxy
				object proxy = persistenceContext.GetProxy(keyToLoad);
				if (proxy != null)
				{
					return ReturnNarrowedProxy(@event, persister, keyToLoad, options, persistenceContext, proxy);
				}
				else
				{
					if (options.IsAllowProxyCreation)
					{
						return CreateProxyIfNecessary(@event, persister, keyToLoad, options, persistenceContext);
					}
					else
					{
						// return a newly loaded object
						return Load(@event, persister, keyToLoad, options);
					}
				}
			}
		}

		/// <summary> 
		/// Given that there is a pre-existing proxy.
		/// Initialize it if necessary; narrow if necessary.
		/// </summary>
		private object ReturnNarrowedProxy(LoadEvent @event, IEntityPersister persister, EntityKey keyToLoad, LoadType options, IPersistenceContext persistenceContext, object proxy)
		{
			log.Debug("entity proxy found in session cache");
			ILazyInitializer li = ((INHibernateProxy)proxy).HibernateLazyInitializer;
			if (li.Unwrap)
			{
				return li.GetImplementation();
			}
			object impl = null;
			if (!options.IsAllowProxyCreation)
			{
				impl = Load(@event, persister, keyToLoad, options);
				// NH Different behavior : NH-1252
				if (impl == null && !options.IsAllowNulls)
				{
					@event.Session.Factory.EntityNotFoundDelegate.HandleEntityNotFound(persister.EntityName, keyToLoad.Identifier);
				}
			}
			if (impl == null && !options.IsAllowProxyCreation && options.ExactPersister)
			{
				// NH Different behavior : NH-1252
				return null;
			}
			return persistenceContext.NarrowProxy((INHibernateProxy)proxy, persister, keyToLoad, impl);
		}

		/// <summary> 
		/// Given that there is no pre-existing proxy.
		/// Check if the entity is already loaded. If it is, return the entity,
		/// otherwise create and return a proxy.
		/// </summary>
		private object CreateProxyIfNecessary(LoadEvent @event, IEntityPersister persister, EntityKey keyToLoad, LoadType options, IPersistenceContext persistenceContext)
		{
			object existing = persistenceContext.GetEntity(keyToLoad);
			if (existing != null)
			{
				// return existing object or initialized proxy (unless deleted)
				log.Debug("entity found in session cache");
				if (options.IsCheckDeleted)
				{
					EntityEntry entry = persistenceContext.GetEntry(existing);
					Status status = entry.Status;
					if (status == Status.Deleted || status == Status.Gone)
					{
						return null;
					}
				}
				return existing;
			}
			else
			{
				log.Debug("creating new proxy for entity");
				// return new uninitialized proxy
				object proxy = persister.CreateProxy(@event.EntityId, @event.Session);
				persistenceContext.BatchFetchQueue.AddBatchLoadableEntityKey(keyToLoad);
				persistenceContext.AddProxy(keyToLoad, (INHibernateProxy)proxy);
				return proxy;
			}
		}

		/// <summary> 
		/// If the class to be loaded has been configured with a cache, then lock
		/// given id in that cache and then perform the load. 
		/// </summary>
		/// <returns> The loaded entity </returns>
		protected virtual object LockAndLoad(LoadEvent @event, IEntityPersister persister, EntityKey keyToLoad, LoadType options, ISessionImplementor source)
		{
			ISoftLock sLock = null;
			CacheKey ck;
			if (persister.HasCache)
			{
				ck = new CacheKey(@event.EntityId, persister.IdentifierType, persister.RootEntityName, source.EntityMode, source.Factory);
				sLock = persister.Cache.Lock(ck, null);
			}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -