Example #1
0
 public bool Equals(EntityUniqueKey that)
 {
     return(that != null && that.EntityName.Equals(entityName) && that.UniqueKeyName.Equals(uniqueKeyName) &&
            // Normally entities are cached by semi-resolved type only, but the initial fix of #1226 causes them to
            // be cached by type too. This may then cause issues (including Stack Overflow Exception) when this
            // happens with the that.keyType being an entity type while its value is an uninitialized proxy: if
            // this.keyType is not an entity type too, its IsEqual will trigger the proxy loading.
            // So we need to short-circuit on keyType inequality, at least till Loader.CacheByUniqueKey is removed.
            // 6.0 TODO: consider removing the keyType.Equals(that.keyType) check, see above comment.
            keyType.Equals(that.keyType) &&
            keyType.IsEqual(that.key, key));
 }
Example #2
0
		/// <summary>
		/// Hydrate the state of an object from the SQL <c>IDataReader</c>, into
		/// an array of "hydrated" values (do not resolve associations yet),
		/// and pass the hydrated state to the session.
		/// </summary>
		private void LoadFromResultSet(IDataReader rs, int i, object obj, string instanceClass, EntityKey key,
		                               string rowIdAlias, LockMode lockMode, ILoadable rootPersister,
		                               ISessionImplementor session)
		{
			object id = key.Identifier;

			// Get the persister for the _subclass_
			ILoadable persister = (ILoadable) Factory.GetEntityPersister(instanceClass);

			if (log.IsDebugEnabled)
			{
				log.Debug("Initializing object from DataReader: " + MessageHelper.InfoString(persister, id));
			}

			bool eagerPropertyFetch = IsEagerPropertyFetchEnabled(i);

			// add temp entry so that the next step is circular-reference
			// safe - only needed because some types don't take proper
			// advantage of two-phase-load (esp. components)
			TwoPhaseLoad.AddUninitializedEntity(key, obj, persister, lockMode, !eagerPropertyFetch, session);

			// This is not very nice (and quite slow):
			string[][] cols = persister == rootPersister
			                  	? EntityAliases[i].SuffixedPropertyAliases
			                  	: EntityAliases[i].GetSuffixedPropertyAliases(persister);

			object[] values = persister.Hydrate(rs, id, obj, rootPersister, cols, eagerPropertyFetch, session);

			object rowId = persister.HasRowId ? rs[rowIdAlias] : null;

			IAssociationType[] ownerAssociationTypes = OwnerAssociationTypes;
			if (ownerAssociationTypes != null && ownerAssociationTypes[i] != null)
			{
				string ukName = ownerAssociationTypes[i].RHSUniqueKeyPropertyName;
				if (ukName != null)
				{
					int index = ((IUniqueKeyLoadable) persister).GetPropertyIndex(ukName);
					IType type = persister.PropertyTypes[index];

					// polymorphism not really handled completely correctly,
					// perhaps...well, actually its ok, assuming that the
					// entity name used in the lookup is the same as the
					// the one used here, which it will be

					EntityUniqueKey euk =
						new EntityUniqueKey(rootPersister.EntityName, ukName, type.SemiResolve(values[index], session, obj), type,
						                    session.EntityMode, session.Factory);
					session.PersistenceContext.AddEntity(euk, obj);
				}
			}

			TwoPhaseLoad.PostHydrate(persister, id, values, rowId, obj, lockMode, !eagerPropertyFetch, session);
		}
		/// <summary> Add an entity to the cache by unique key</summary>
		public void AddEntity(EntityUniqueKey euk, object entity)
		{
			entitiesByUniqueKey[euk] = entity;
		}
		/// <summary> Get an entity cached by unique key</summary>
		public object GetEntity(EntityUniqueKey euk)
		{
			object result;
			entitiesByUniqueKey.TryGetValue(euk, out result);
			return result;
		}
Example #5
0
		/// <summary> 
		/// Load an instance by a unique key that is not the primary key. 
		/// </summary>
		/// <param name="entityName">The name of the entity to load </param>
		/// <param name="uniqueKeyPropertyName">The name of the property defining the uniqie key. </param>
		/// <param name="key">The unique key property value. </param>
		/// <param name="session">The originating session. </param>
		/// <returns> The loaded entity </returns>
		public object LoadByUniqueKey(string entityName, string uniqueKeyPropertyName, object key, ISessionImplementor session)
		{

			ISessionFactoryImplementor factory = session.Factory;
			IUniqueKeyLoadable persister = (IUniqueKeyLoadable)factory.GetEntityPersister(entityName);

			//TODO: implement caching?! proxies?!

			EntityUniqueKey euk =
				new EntityUniqueKey(entityName, uniqueKeyPropertyName, key, GetIdentifierOrUniqueKeyType(factory),
									session.EntityMode, session.Factory);

			IPersistenceContext persistenceContext = session.PersistenceContext;
			try
			{
				object result = persistenceContext.GetEntity(euk);
				if (result == null)
				{
					result = persister.LoadByUniqueKey(uniqueKeyPropertyName, key, session);
				}
				return result == null ? null : persistenceContext.ProxyFor(result);
			}
			catch (HibernateException)
			{
				// Do not call Convert on HibernateExceptions
				throw;
			}
			catch (Exception sqle)
			{
				throw ADOExceptionHelper.Convert(factory.SQLExceptionConverter, sqle, "Error performing LoadByUniqueKey");
			}
		}
 public bool Equals(EntityUniqueKey that)
 {
     return(that == null ? false :
            that.EntityName.Equals(entityName) && that.UniqueKeyName.Equals(uniqueKeyName) && keyType.IsEqual(that.key, key, entityMode));
 }
		public bool Equals(EntityUniqueKey that)
		{
			return that == null ? false :
				that.EntityName.Equals(entityName) && that.UniqueKeyName.Equals(uniqueKeyName) && keyType.IsEqual(that.key, key, entityMode);
		}