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