private object AssembleCacheEntry(CacheEntry entry, object id, IEntityPersister persister, LoadEvent @event) { object optionalObject = @event.InstanceToLoad; IEventSource session = @event.Session; ISessionFactoryImplementor factory = session.Factory; if (log.IsDebugEnabled) { log.Debug("assembling entity from second-level cache: " + MessageHelper.InfoString(persister, id, factory)); } IEntityPersister subclassPersister = factory.GetEntityPersister(entry.Subclass); object result = optionalObject ?? session.Instantiate(subclassPersister, id); // make it circular-reference safe TwoPhaseLoad.AddUninitializedCachedEntity(new EntityKey(id, subclassPersister, session.EntityMode), result, subclassPersister, LockMode.None, entry.AreLazyPropertiesUnfetched, entry.Version, session); IType[] types = subclassPersister.PropertyTypes; object[] values = entry.Assemble(result, id, subclassPersister, session.Interceptor, session); // intializes result by side-effect TypeFactory.DeepCopy(values, types, subclassPersister.PropertyUpdateability, values, session); object version = Versioning.GetVersion(values, subclassPersister); if (log.IsDebugEnabled) { log.Debug("Cached Version: " + version); } IPersistenceContext persistenceContext = session.PersistenceContext; persistenceContext.AddEntry(result, Status.Loaded, values, null, id, version, LockMode.None, true, subclassPersister, false, entry.AreLazyPropertiesUnfetched); subclassPersister.AfterInitialize(result, entry.AreLazyPropertiesUnfetched, session); persistenceContext.InitializeNonLazyCollections(); // upgrade the lock if necessary: //lock(result, lockMode); //PostLoad is needed for EJB3 //TODO: reuse the PostLoadEvent... PostLoadEvent postLoadEvent = new PostLoadEvent(session); postLoadEvent.Entity = result; postLoadEvent.Id = id; postLoadEvent.Persister = persister; IPostLoadEventListener[] listeners = session.Listeners.PostLoadEventListeners; for (int i = 0; i < listeners.Length; i++) { listeners[i].OnPostLoad(postLoadEvent); } return(result); }
/// <summary> /// Generates an appropriate EntityEntry instance and adds it /// to the event source's internal caches. /// </summary> public static EntityEntry AddEntry( this IPersistenceContext context, object entity, Status status, object[] loadedState, object rowId, object id, object version, LockMode lockMode, bool existsInDatabase, IEntityPersister persister, bool disableVersionIncrement) { if (context is StatefulPersistenceContext statefulPersistence) { return(statefulPersistence.AddEntry( entity, status, loadedState, rowId, id, version, lockMode, existsInDatabase, persister, disableVersionIncrement)); } #pragma warning disable 618 return(context.AddEntry( entity, status, loadedState, rowId, id, version, lockMode, existsInDatabase, persister, disableVersionIncrement, loadedState?.Any(o => o == LazyPropertyInitializer.UnfetchedProperty) == true)); #pragma warning restore 618 }
private async Task <object> AssembleCacheEntryAsync(CacheEntry entry, object id, IEntityPersister persister, LoadEvent @event, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); object optionalObject = @event.InstanceToLoad; IEventSource session = @event.Session; ISessionFactoryImplementor factory = session.Factory; if (log.IsDebugEnabled()) { log.Debug("assembling entity from second-level cache: {0}", MessageHelper.InfoString(persister, id, factory)); } IEntityPersister subclassPersister = factory.GetEntityPersister(entry.Subclass); object result = optionalObject ?? session.Instantiate(subclassPersister, id); // make it circular-reference safe EntityKey entityKey = session.GenerateEntityKey(id, subclassPersister); TwoPhaseLoad.AddUninitializedCachedEntity(entityKey, result, subclassPersister, LockMode.None, entry.Version, session); IType[] types = subclassPersister.PropertyTypes; object[] values = await(entry.AssembleAsync(result, id, subclassPersister, session.Interceptor, session, cancellationToken)).ConfigureAwait(false); // intializes result by side-effect TypeHelper.DeepCopy(values, types, subclassPersister.PropertyUpdateability, values, session); object version = Versioning.GetVersion(values, subclassPersister); if (log.IsDebugEnabled()) { log.Debug("Cached Version: {0}", version); } IPersistenceContext persistenceContext = session.PersistenceContext; bool isReadOnly = session.DefaultReadOnly; if (persister.IsMutable) { object proxy = persistenceContext.GetProxy(entityKey); if (proxy != null) { // this is already a proxy for this impl // only set the status to read-only if the proxy is read-only isReadOnly = ((INHibernateProxy)proxy).HibernateLazyInitializer.ReadOnly; } } else { isReadOnly = true; } persistenceContext.AddEntry( result, isReadOnly ? Status.ReadOnly : Status.Loaded, values, null, id, version, LockMode.None, true, subclassPersister, false); subclassPersister.AfterInitialize(result, session); await(persistenceContext.InitializeNonLazyCollectionsAsync(cancellationToken)).ConfigureAwait(false); // upgrade the lock if necessary: //lock(result, lockMode); //PostLoad is needed for EJB3 //TODO: reuse the PostLoadEvent... PostLoadEvent postLoadEvent = new PostLoadEvent(session); postLoadEvent.Entity = result; postLoadEvent.Id = id; postLoadEvent.Persister = persister; IPostLoadEventListener[] listeners = session.Listeners.PostLoadEventListeners; for (int i = 0; i < listeners.Length; i++) { listeners[i].OnPostLoad(postLoadEvent); } return(result); }