Exemple #1
0
        /// <summary>
        /// Register the "hydrated" state of an entity instance, after the first step of 2-phase loading.
        ///
        /// Add the "hydrated state" (an array) of an uninitialized entity to the session. We don't try
        /// to resolve any associations yet, because there might be other entities waiting to be
        /// read from the JDBC result set we are currently processing
        /// </summary>
        public static void PostHydrate(IEntityPersister persister, object id, object[] values, object rowId, object obj, LockMode lockMode, bool lazyPropertiesAreUnfetched, ISessionImplementor session)
        {
            object version = Versioning.GetVersion(values, persister);

            session.PersistenceContext.AddEntry(obj, Status.Loading, values, rowId, id, version, lockMode, true, persister, false, lazyPropertiesAreUnfetched);

            if (log.IsDebugEnabled && version != null)
            {
                System.String versionStr = persister.IsVersioned ? persister.VersionType.ToLoggableString(version, session.Factory) : "null";
                log.Debug("Version: " + versionStr);
            }
        }
Exemple #2
0
        /// <summary>
        /// Perform the second step of 2-phase load. Fully initialize the entity instance.
        /// After processing a JDBC result set, we "resolve" all the associations
        /// between the entities which were instantiated and had their state
        /// "hydrated" into an array
        /// </summary>
        internal static void InitializeEntity(object entity, bool readOnly, ISessionImplementor session, PreLoadEvent preLoadEvent, PostLoadEvent postLoadEvent,
                                              Action <IEntityPersister, CachePutData> cacheBatchingHandler)
        {
            //TODO: Should this be an InitializeEntityEventListener??? (watch out for performance!)

            bool statsEnabled = session.Factory.Statistics.IsStatisticsEnabled;
            var  stopWath     = new Stopwatch();

            if (statsEnabled)
            {
                stopWath.Start();
            }

            IPersistenceContext persistenceContext = session.PersistenceContext;
            EntityEntry         entityEntry        = persistenceContext.GetEntry(entity);

            if (entityEntry == null)
            {
                throw new AssertionFailure("possible non-threadsafe access to the session");
            }
            IEntityPersister persister = entityEntry.Persister;
            object           id        = entityEntry.Id;

            object[] hydratedState = entityEntry.LoadedState;

            if (log.IsDebugEnabled())
            {
                log.Debug("resolving associations for {0}", MessageHelper.InfoString(persister, id, session.Factory));
            }

            IType[] types = persister.PropertyTypes;
            var     collectionToResolveIndexes = new List <int>(hydratedState.Length);

            for (int i = 0; i < hydratedState.Length; i++)
            {
                object value = hydratedState[i];
                if (!Equals(LazyPropertyInitializer.UnfetchedProperty, value) && !(Equals(BackrefPropertyAccessor.Unknown, value)))
                {
                    if (types[i].IsCollectionType)
                    {
                        // Resolve them last, because they may depend on other properties if they use a property-ref
                        collectionToResolveIndexes.Add(i);
                        continue;
                    }

                    hydratedState[i] = types[i].ResolveIdentifier(value, session, entity);
                }
            }

            foreach (var i in collectionToResolveIndexes)
            {
                hydratedState[i] = types[i].ResolveIdentifier(hydratedState[i], session, entity);
            }

            //Must occur after resolving identifiers!
            if (session.IsEventSource)
            {
                preLoadEvent.Entity    = entity;
                preLoadEvent.State     = hydratedState;
                preLoadEvent.Id        = id;
                preLoadEvent.Persister = persister;
                IPreLoadEventListener[] listeners = session.Listeners.PreLoadEventListeners;
                for (int i = 0; i < listeners.Length; i++)
                {
                    listeners[i].OnPreLoad(preLoadEvent);
                }
            }

            persister.SetPropertyValues(entity, hydratedState);

            ISessionFactoryImplementor factory = session.Factory;

            if (persister.HasCache && session.CacheMode.HasFlag(CacheMode.Put))
            {
                if (log.IsDebugEnabled())
                {
                    log.Debug("adding entity to second-level cache: {0}", MessageHelper.InfoString(persister, id, session.Factory));
                }

                object     version = Versioning.GetVersion(hydratedState, persister);
                CacheEntry entry   =
                    CacheEntry.Create(hydratedState, persister, version, session, entity);
                CacheKey cacheKey = session.GenerateCacheKey(id, persister.IdentifierType, persister.RootEntityName);

                if (cacheBatchingHandler != null && persister.IsBatchLoadable)
                {
                    cacheBatchingHandler(
                        persister,
                        new CachePutData(
                            cacheKey,
                            persister.CacheEntryStructure.Structure(entry),
                            version,
                            persister.IsVersioned ? persister.VersionType.Comparator : null,
                            UseMinimalPuts(session, entityEntry)));
                }
                else
                {
                    bool put =
                        persister.Cache.Put(cacheKey, persister.CacheEntryStructure.Structure(entry), session.Timestamp, version,
                                            persister.IsVersioned ? persister.VersionType.Comparator : null,
                                            UseMinimalPuts(session, entityEntry));

                    if (put && factory.Statistics.IsStatisticsEnabled)
                    {
                        factory.StatisticsImplementor.SecondLevelCachePut(persister.Cache.RegionName);
                    }
                }
            }

            bool isReallyReadOnly = readOnly;

            if (!persister.IsMutable)
            {
                isReallyReadOnly = true;
            }
            else
            {
                object proxy = persistenceContext.GetProxy(entityEntry.EntityKey);
                if (proxy != null)
                {
                    // there is already a proxy for this impl
                    // only set the status to read-only if the proxy is read-only
                    isReallyReadOnly = ((INHibernateProxy)proxy).HibernateLazyInitializer.ReadOnly;
                }
            }

            if (isReallyReadOnly)
            {
                //no need to take a snapshot - this is a
                //performance optimization, but not really
                //important, except for entities with huge
                //mutable property values
                persistenceContext.SetEntryStatus(entityEntry, Status.ReadOnly);
            }
            else
            {
                //take a snapshot
                TypeHelper.DeepCopy(hydratedState, persister.PropertyTypes, persister.PropertyUpdateability, hydratedState, session);
                persistenceContext.SetEntryStatus(entityEntry, Status.Loaded);
            }

            persister.AfterInitialize(entity, session);

            if (session.IsEventSource)
            {
                postLoadEvent.Entity    = entity;
                postLoadEvent.Id        = id;
                postLoadEvent.Persister = persister;
                IPostLoadEventListener[] listeners = session.Listeners.PostLoadEventListeners;
                for (int i = 0; i < listeners.Length; i++)
                {
                    listeners[i].OnPostLoad(postLoadEvent);
                }
            }

            if (log.IsDebugEnabled())
            {
                log.Debug("done materializing entity {0}", MessageHelper.InfoString(persister, id, session.Factory));
            }

            if (statsEnabled)
            {
                stopWath.Stop();
                factory.StatisticsImplementor.LoadEntity(persister.EntityName, stopWath.Elapsed);
            }
        }
        /// <summary>
        /// Perform the second step of 2-phase load. Fully initialize the entity instance.
        /// After processing a JDBC result set, we "resolve" all the associations
        /// between the entities which were instantiated and had their state
        /// "hydrated" into an array
        /// </summary>
        public static async Task InitializeEntityAsync(object entity, bool readOnly, ISessionImplementor session, PreLoadEvent preLoadEvent, PostLoadEvent postLoadEvent, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            //TODO: Should this be an InitializeEntityEventListener??? (watch out for performance!)

            bool statsEnabled = session.Factory.Statistics.IsStatisticsEnabled;
            var  stopWath     = new Stopwatch();

            if (statsEnabled)
            {
                stopWath.Start();
            }

            IPersistenceContext persistenceContext = session.PersistenceContext;
            EntityEntry         entityEntry        = persistenceContext.GetEntry(entity);

            if (entityEntry == null)
            {
                throw new AssertionFailure("possible non-threadsafe access to the session");
            }
            IEntityPersister persister = entityEntry.Persister;
            object           id        = entityEntry.Id;

            object[] hydratedState = entityEntry.LoadedState;

            if (log.IsDebugEnabled)
            {
                log.Debug("resolving associations for " + MessageHelper.InfoString(persister, id, session.Factory));
            }

            IType[] types = persister.PropertyTypes;
            for (int i = 0; i < hydratedState.Length; i++)
            {
                object value = hydratedState[i];
                if (!Equals(LazyPropertyInitializer.UnfetchedProperty, value) && !(Equals(BackrefPropertyAccessor.Unknown, value)))
                {
                    hydratedState[i] = await(types[i].ResolveIdentifierAsync(value, session, entity, cancellationToken)).ConfigureAwait(false);
                }
            }

            //Must occur after resolving identifiers!
            if (session.IsEventSource)
            {
                preLoadEvent.Entity    = entity;
                preLoadEvent.State     = hydratedState;
                preLoadEvent.Id        = id;
                preLoadEvent.Persister = persister;
                IPreLoadEventListener[] listeners = session.Listeners.PreLoadEventListeners;
                for (int i = 0; i < listeners.Length; i++)
                {
                    await(listeners[i].OnPreLoadAsync(preLoadEvent, cancellationToken)).ConfigureAwait(false);
                }
            }

            persister.SetPropertyValues(entity, hydratedState);

            ISessionFactoryImplementor factory = session.Factory;

            if (persister.HasCache && session.CacheMode.HasFlag(CacheMode.Put))
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("adding entity to second-level cache: " + MessageHelper.InfoString(persister, id, session.Factory));
                }

                object     version = Versioning.GetVersion(hydratedState, persister);
                CacheEntry entry   =
                    new CacheEntry(hydratedState, persister, entityEntry.LoadedWithLazyPropertiesUnfetched, version, session, entity);
                CacheKey cacheKey = session.GenerateCacheKey(id, persister.IdentifierType, persister.RootEntityName);
                bool     put      =
                    await(persister.Cache.PutAsync(cacheKey, persister.CacheEntryStructure.Structure(entry), session.Timestamp, version,
                                                   persister.IsVersioned ? persister.VersionType.Comparator : null,
                                                   UseMinimalPuts(session, entityEntry), cancellationToken)).ConfigureAwait(false);

                if (put && factory.Statistics.IsStatisticsEnabled)
                {
                    factory.StatisticsImplementor.SecondLevelCachePut(persister.Cache.RegionName);
                }
            }

            bool isReallyReadOnly = readOnly;

            if (!persister.IsMutable)
            {
                isReallyReadOnly = true;
            }
            else
            {
                object proxy = persistenceContext.GetProxy(entityEntry.EntityKey);
                if (proxy != null)
                {
                    // there is already a proxy for this impl
                    // only set the status to read-only if the proxy is read-only
                    isReallyReadOnly = ((INHibernateProxy)proxy).HibernateLazyInitializer.ReadOnly;
                }
            }

            if (isReallyReadOnly)
            {
                //no need to take a snapshot - this is a
                //performance optimization, but not really
                //important, except for entities with huge
                //mutable property values
                persistenceContext.SetEntryStatus(entityEntry, Status.ReadOnly);
            }
            else
            {
                //take a snapshot
                TypeHelper.DeepCopy(hydratedState, persister.PropertyTypes, persister.PropertyUpdateability, hydratedState, session);
                persistenceContext.SetEntryStatus(entityEntry, Status.Loaded);
            }

            persister.AfterInitialize(entity, entityEntry.LoadedWithLazyPropertiesUnfetched, session);

            if (session.IsEventSource)
            {
                postLoadEvent.Entity    = entity;
                postLoadEvent.Id        = id;
                postLoadEvent.Persister = persister;
                IPostLoadEventListener[] listeners = session.Listeners.PostLoadEventListeners;
                for (int i = 0; i < listeners.Length; i++)
                {
                    listeners[i].OnPostLoad(postLoadEvent);
                }
            }

            if (log.IsDebugEnabled)
            {
                log.Debug("done materializing entity " + MessageHelper.InfoString(persister, id, session.Factory));
            }

            if (statsEnabled)
            {
                stopWath.Stop();
                factory.StatisticsImplementor.LoadEntity(persister.EntityName, stopWath.Elapsed);
            }
        }
        /// <summary>
        /// Perform the second step of 2-phase load. Fully initialize the entity instance.
        /// After processing a JDBC result set, we "resolve" all the associations
        /// between the entities which were instantiated and had their state
        /// "hydrated" into an array
        /// </summary>
        public static void InitializeEntity(object entity, bool readOnly, ISessionImplementor session, PreLoadEvent preLoadEvent, PostLoadEvent postLoadEvent)
        {
            //TODO: Should this be an InitializeEntityEventListener??? (watch out for performance!)

            bool statsEnabled = session.Factory.Statistics.IsStatisticsEnabled;
            var  stopWath     = new Stopwatch();

            if (statsEnabled)
            {
                stopWath.Start();
            }

            IPersistenceContext persistenceContext = session.PersistenceContext;
            EntityEntry         entityEntry        = persistenceContext.GetEntry(entity);

            if (entityEntry == null)
            {
                throw new AssertionFailure("possible non-threadsafe access to the session");
            }
            IEntityPersister persister = entityEntry.Persister;
            object           id        = entityEntry.Id;

            object[] hydratedState = entityEntry.LoadedState;

            if (log.IsDebugEnabled)
            {
                log.Debug("resolving associations for " + MessageHelper.InfoString(persister, id, session.Factory));
            }

            IType[] types = persister.PropertyTypes;
            for (int i = 0; i < hydratedState.Length; i++)
            {
                object value = hydratedState[i];
                if (value != LazyPropertyInitializer.UnfetchedProperty && value != BackrefPropertyAccessor.Unknown)
                {
                    hydratedState[i] = types[i].ResolveIdentifier(value, session, entity);
                }
            }

            //Must occur after resolving identifiers!
            if (session.IsEventSource)
            {
                preLoadEvent.Entity    = entity;
                preLoadEvent.State     = hydratedState;
                preLoadEvent.Id        = id;
                preLoadEvent.Persister = persister;
                IPreLoadEventListener[] listeners = session.Listeners.PreLoadEventListeners;
                for (int i = 0; i < listeners.Length; i++)
                {
                    listeners[i].OnPreLoad(preLoadEvent);
                }
            }

            persister.SetPropertyValues(entity, hydratedState, session.EntityMode);

            ISessionFactoryImplementor factory = session.Factory;

            if (persister.HasCache && ((session.CacheMode & CacheMode.Put) == CacheMode.Put))
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("adding entity to second-level cache: " + MessageHelper.InfoString(persister, id, session.Factory));
                }

                object     version = Versioning.GetVersion(hydratedState, persister);
                CacheEntry entry   =
                    new CacheEntry(hydratedState, persister, entityEntry.LoadedWithLazyPropertiesUnfetched, version, session, entity);
                CacheKey cacheKey = new CacheKey(id, persister.IdentifierType, persister.RootEntityName, session.EntityMode, session.Factory);
                bool     put      =
                    persister.Cache.Put(cacheKey, persister.CacheEntryStructure.Structure(entry), session.Timestamp, version,
                                        persister.IsVersioned ? persister.VersionType.Comparator : null,
                                        UseMinimalPuts(session, entityEntry));

                if (put && factory.Statistics.IsStatisticsEnabled)
                {
                    factory.StatisticsImplementor.SecondLevelCachePut(persister.Cache.RegionName);
                }
            }

            if (readOnly || !persister.IsMutable)
            {
                //no need to take a snapshot - this is a
                //performance optimization, but not really
                //important, except for entities with huge
                //mutable property values
                persistenceContext.SetEntryStatus(entityEntry, Status.ReadOnly);
            }
            else
            {
                //take a snapshot
                TypeFactory.DeepCopy(hydratedState, persister.PropertyTypes, persister.PropertyUpdateability, hydratedState, session);
                persistenceContext.SetEntryStatus(entityEntry, Status.Loaded);
            }

            persister.AfterInitialize(entity, entityEntry.LoadedWithLazyPropertiesUnfetched, session);

            if (session.IsEventSource)
            {
                postLoadEvent.Entity    = entity;
                postLoadEvent.Id        = id;
                postLoadEvent.Persister = persister;
                IPostLoadEventListener[] listeners = session.Listeners.PostLoadEventListeners;
                for (int i = 0; i < listeners.Length; i++)
                {
                    listeners[i].OnPostLoad(postLoadEvent);
                }
            }

            if (log.IsDebugEnabled)
            {
                log.Debug("done materializing entity " + MessageHelper.InfoString(persister, id, session.Factory));
            }

            if (statsEnabled)
            {
                stopWath.Stop();
                factory.StatisticsImplementor.LoadEntity(persister.EntityName, stopWath.Elapsed);
            }
        }