コード例 #1
0
        /// <summary>
        /// Apply the <see cref="ICacheAssembler.AssembleAsync(object,ISessionImplementor,object,CancellationToken)" /> operation across a series of values.
        /// </summary>
        /// <param name="row">The cached values.</param>
        /// <param name="types">The value types.</param>
        /// <param name="typeIndexes">The indexes of types to assemble.</param>
        /// <param name="session">The originating session.</param>
        /// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
        /// <returns>A new array of assembled values.</returns>
        internal static async Task <object[]> AssembleAsync(
            object[] row,
            ICacheAssembler[] types,
            IList <int> typeIndexes,
            ISessionImplementor session, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            var assembled = new object[row.Length];

            foreach (var i in typeIndexes)
            {
                var value = row[i];
                if (Equals(LazyPropertyInitializer.UnfetchedProperty, value) || Equals(BackrefPropertyAccessor.Unknown, value))
                {
                    assembled[i] = value;
                }
                else
                {
                    var type = CustomEntityTypeMapper.Map(types[i] as IType);
                    if (type != null)
                    {
                        assembled[i] = await(type.AssembleAsync(row[i], session, null, cancellationToken)).ConfigureAwait(false);
                    }
                    else
                    {
                        assembled[i] = await(types[i].AssembleAsync(row[i], session, null, cancellationToken)).ConfigureAwait(false);
                    }
                }
            }

            return(assembled);
        }
コード例 #2
0
        protected override async Task <object[]> GetResultRowAsync(object[] row, DbDataReader rs, ISessionImplementor session, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            object[] result;

            if (translator.HasProjection)
            {
                result = new object[ResultTypes.Length];

                for (int i = 0, position = 0; i < result.Length; i++)
                {
                    int numColumns = ResultTypes[i].GetColumnSpan(session.Factory);

                    if (numColumns > 1)
                    {
                        string[] typeColumnAliases = ArrayHelper.Slice(cachedProjectedColumnAliases, position, numColumns);
                        result[i] = await(CustomEntityTypeMapper.Map(ResultTypes[i]).NullSafeGetAsync(rs, typeColumnAliases, session, null, cancellationToken)).ConfigureAwait(false);
                    }
                    else
                    {
                        result[i] = await(CustomEntityTypeMapper.Map(ResultTypes[i]).NullSafeGetAsync(rs, cachedProjectedColumnAliases[position], session, null, cancellationToken)).ConfigureAwait(false);
                    }
                    position += numColumns;
                }
            }
            else
            {
                result = ToResultRow(row);
            }
            return(result);
        }
コード例 #3
0
        /// <summary>
        /// Apply the <see cref="ICacheAssembler.AssembleAsync(object,ISessionImplementor,object,CancellationToken)" /> operation across a series of values.
        /// </summary>
        /// <param name="row">The values</param>
        /// <param name="types">The value types</param>
        /// <param name="session">The originating session</param>
        /// <param name="owner">The entity "owning" the values</param>
        /// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
        /// <returns></returns>
        public static async Task <object[]> AssembleAsync(object[] row, ICacheAssembler[] types, ISessionImplementor session, object owner, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            var assembled = new object[row.Length];

            for (int i = 0; i < row.Length; i++)
            {
                if (Equals(LazyPropertyInitializer.UnfetchedProperty, row[i]) || Equals(BackrefPropertyAccessor.Unknown, row[i]))
                {
                    assembled[i] = row[i];
                }
                else
                {
                    var type = CustomEntityTypeMapper.Map(types[i] as IType);
                    if (type != null)
                    {
                        assembled[i] = await(type.AssembleAsync(row[i], session, owner, cancellationToken)).ConfigureAwait(false);
                    }
                    else
                    {
                        assembled[i] = await(types[i].AssembleAsync(row[i], session, owner, cancellationToken)).ConfigureAwait(false);
                    }
                }
            }
            return(assembled);
        }
コード例 #4
0
        /// <summary>
        /// Apply the <see cref="ICacheAssembler.Assemble" /> operation across a series of values.
        /// </summary>
        /// <param name="row">The values</param>
        /// <param name="types">The value types</param>
        /// <param name="session">The originating session</param>
        /// <param name="owner">The entity "owning" the values</param>
        /// <returns></returns>
        public static object[] Assemble(object[] row, ICacheAssembler[] types, ISessionImplementor session, object owner)
        {
            var assembled = new object[row.Length];

            for (int i = 0; i < row.Length; i++)
            {
                if (Equals(LazyPropertyInitializer.UnfetchedProperty, row[i]) || Equals(BackrefPropertyAccessor.Unknown, row[i]))
                {
                    assembled[i] = row[i];
                }
                else
                {
                    var type = CustomEntityTypeMapper.Map(types[i] as IType);
                    if (type != null)
                    {
                        assembled[i] = type.Assemble(row[i], session, owner);
                    }
                    else
                    {
                        assembled[i] = types[i].Assemble(row[i], session, owner);
                    }
                }
            }
            return(assembled);
        }
コード例 #5
0
        /// <summary>
        /// Apply the <see cref="ICacheAssembler.Assemble" /> operation across a series of values.
        /// </summary>
        /// <param name="row">The cached values.</param>
        /// <param name="types">The value types.</param>
        /// <param name="typeIndexes">The indexes of types to assemble.</param>
        /// <param name="session">The originating session.</param>
        /// <returns>A new array of assembled values.</returns>
        internal static object[] Assemble(
            object[] row,
            ICacheAssembler[] types,
            IList <int> typeIndexes,
            ISessionImplementor session)
        {
            var assembled = new object[row.Length];

            foreach (var i in typeIndexes)
            {
                var value = row[i];
                if (Equals(LazyPropertyInitializer.UnfetchedProperty, value) || Equals(BackrefPropertyAccessor.Unknown, value))
                {
                    assembled[i] = value;
                }
                else
                {
                    var type = CustomEntityTypeMapper.Map(types[i] as IType);
                    if (type != null)
                    {
                        assembled[i] = type.Assemble(row[i], session, null);
                    }
                    else
                    {
                        assembled[i] = types[i].Assemble(row[i], session, null);
                    }
                }
            }

            return(assembled);
        }
コード例 #6
0
        protected override object[] GetResultRow(object[] row, DbDataReader rs, ISessionImplementor session)
        {
            object[] result;

            if (translator.HasProjection)
            {
                result = new object[ResultTypes.Length];

                for (int i = 0, position = 0; i < result.Length; i++)
                {
                    int numColumns = ResultTypes[i].GetColumnSpan(session.Factory);

                    if (numColumns > 1)
                    {
                        string[] typeColumnAliases = ArrayHelper.Slice(cachedProjectedColumnAliases, position, numColumns);
                        result[i] = CustomEntityTypeMapper.Map(ResultTypes[i]).NullSafeGet(rs, typeColumnAliases, session, null);
                    }
                    else
                    {
                        result[i] = CustomEntityTypeMapper.Map(ResultTypes[i]).NullSafeGet(rs, cachedProjectedColumnAliases[position], session, null);
                    }
                    position += numColumns;
                }
            }
            else
            {
                result = ToResultRow(row);
            }
            return(result);
        }
コード例 #7
0
        public override void Resolve(bool generateJoin, bool implicitJoin, string classAlias, IASTNode parent)
        {
            // If this dot has already been resolved, stop now.
            if (IsResolved)
            {
                return;
            }

            IType propertyType = CustomEntityTypeMapper.Map(PrepareLhs());             // Prepare the left hand side and get the data type.

            // If there is no data type for this node, and we're at the end of the path (top most dot node), then
            // this might be a Java constant.
            if (propertyType == null)
            {
                if (parent == null)
                {
                    Walker.LiteralProcessor.LookupConstant(this);
                }
                // If the propertyType is null and there isn't a parent, just
                // stop now... there was a problem resolving the node anyway.
                return;
            }

            if (propertyType.IsComponentType)
            {
                // The property is a component...
                CheckLhsIsNotCollection();
                DereferenceComponent(parent);
                InitText();
            }
            else if (propertyType.IsEntityType)
            {
                // The property is another class..
                CheckLhsIsNotCollection();
                DereferenceEntity(( EntityType )propertyType, implicitJoin, classAlias, generateJoin, parent);
                InitText();
            }
            else if (propertyType.IsCollectionType)
            {
                // The property is a collection...
                CheckLhsIsNotCollection();
                DereferenceCollection((CollectionType)propertyType, implicitJoin, false, classAlias);
            }
            else
            {
                // Otherwise, this is a primitive type.
                if (!CollectionProperties.IsAnyCollectionProperty(_propertyName))
                {
                    CheckLhsIsNotCollection();
                }
                _dereferenceType = DerefPrimitive;
                InitText();
            }

            IsResolved = true;
        }
コード例 #8
0
 private static bool Dirty(StandardProperty[] properties, object[] currentState, object[] previousState, bool[][] includeColumns, ISessionImplementor session, int i)
 {
     if (Equals(LazyPropertyInitializer.UnfetchedProperty, currentState[i]))
     {
         return(false);
     }
     if (Equals(LazyPropertyInitializer.UnfetchedProperty, previousState[i]))
     {
         return(true);
     }
     return(properties[i].IsDirtyCheckable() &&
            CustomEntityTypeMapper.Map(properties[i].Type).IsDirty(previousState[i], currentState[i], includeColumns[i], session));
 }
コード例 #9
0
 private static async Task <bool> DirtyAsync(StandardProperty[] properties, object[] currentState, object[] previousState, bool[][] includeColumns, ISessionImplementor session, int i, CancellationToken cancellationToken)
 {
     cancellationToken.ThrowIfCancellationRequested();
     if (Equals(LazyPropertyInitializer.UnfetchedProperty, currentState[i]))
     {
         return(false);
     }
     if (Equals(LazyPropertyInitializer.UnfetchedProperty, previousState[i]))
     {
         return(true);
     }
     return(properties[i].IsDirtyCheckable() &&
            await(CustomEntityTypeMapper.Map(properties[i].Type).IsDirtyAsync(previousState[i], currentState[i], includeColumns[i], session, cancellationToken)).ConfigureAwait(false));
 }
コード例 #10
0
        protected override object[] GetResultRow(object[] row, DbDataReader rs, ISessionImplementor session)
        {
            object[] resultRow;

            if (_hasScalars)
            {
                string[][] scalarColumns = _scalarColumnNames;
                int        queryCols     = ResultTypes.Length;
                resultRow = new object[queryCols];
                for (int i = 0; i < queryCols; i++)
                {
                    resultRow[i] = CustomEntityTypeMapper.Map(ResultTypes[i]).NullSafeGet(rs, scalarColumns[i], session, null);
                }
            }
            else
            {
                resultRow = ToResultRow(row);
            }

            return(resultRow);
        }
コード例 #11
0
        protected override async Task <object[]> GetResultRowAsync(object[] row, DbDataReader rs, ISessionImplementor session, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            object[] resultRow;

            if (_hasScalars)
            {
                string[][] scalarColumns = _scalarColumnNames;
                int        queryCols     = ResultTypes.Length;
                resultRow = new object[queryCols];
                for (int i = 0; i < queryCols; i++)
                {
                    resultRow[i] = await(CustomEntityTypeMapper.Map(ResultTypes[i]).NullSafeGetAsync(rs, scalarColumns[i], session, null, cancellationToken)).ConfigureAwait(false);
                }
            }
            else
            {
                resultRow = ToResultRow(row);
            }

            return(resultRow);
        }
コード例 #12
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 async Task InitializeEntityAsync(object entity, bool readOnly, ISessionImplementor session, PreLoadEvent preLoadEvent, PostLoadEvent postLoadEvent,
                                                         Action <IEntityPersister, CachePutData> cacheBatchingHandler, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            //TODO: Should this be an InitializeEntityEventListener??? (watch out for performance!)

            Stopwatch stopWatch = null;

            if (session.Factory.Statistics.IsStatisticsEnabled)
            {
                stopWatch = Stopwatch.StartNew();
            }

            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] = await(CustomEntityTypeMapper.Map(types[i]).ResolveIdentifierAsync(value, session, entity, cancellationToken)).ConfigureAwait(false);
                }
            }

            foreach (var i in collectionToResolveIndexes)
            {
                hydratedState[i] = await(CustomEntityTypeMapper.Map(types[i]).ResolveIdentifierAsync(hydratedState[i], 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: {0}", MessageHelper.InfoString(persister, id, session.Factory));
                }

                object     version = Versioning.GetVersion(hydratedState, persister);
                CacheEntry entry   =
                    await(CacheEntry.CreateAsync(hydratedState, persister, version, session, entity, cancellationToken)).ConfigureAwait(false);
                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 =
                        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, 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 (stopWatch != null)
            {
                stopWatch.Stop();
                factory.StatisticsImplementor.LoadEntity(persister.EntityName, stopWatch.Elapsed);
            }
        }