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)); }
/// <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; }
/// <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); }