protected override void DeleteEntity(IEventSource session, object entity,

            EntityEntry entityEntry, bool isCascadeDeleteEnabled,

            IEntityPersister persister, ISet transientEntities)
        {
            if (entity is IPermanent)
            {

                var e = (IPermanent)entity;

                e.IsDeleted = true;

                CascadeBeforeDelete(session, persister, entity, entityEntry, transientEntities);

                CascadeAfterDelete(session, persister, entity, transientEntities);

            }

            else
            {

                base.DeleteEntity(session, entity, entityEntry, isCascadeDeleteEnabled,

                                  persister, transientEntities);

            }
        }
 protected override void DeleteEntity(IEventSource session, object entity, EntityEntry entityEntry,
     bool isCascadeDeleteEnabled,
     IEntityPersister persister, ISet<object> transientEntities)
 {
     var entityValue = entity as EntityBase;
     if (entityValue != null)
     {
         entityValue.Deactive = true;
         entityValue.UpdatedBy = EntityConstant.UpdatedBy;
         entityValue.UpdatedOn = DateTime.Now;
     }
     base.DeleteEntity(session, entity, entityEntry, isCascadeDeleteEnabled, persister, transientEntities);
 }
示例#3
0
 protected override void DeleteEntity(IEventSource session, object entity, EntityEntry entityEntry, bool isCascadeDeleteEnabled, IEntityPersister persister, ISet transientEntities)
 {
     //need to implement the condition check
     if (entity is DomainEntity)
     {
         ((DomainEntity)entity).IsDeleted = true;
         this.CascadeBeforeDelete(session, persister, entity, entityEntry, transientEntities);
         this.CascadeAfterDelete(session, persister, entity, transientEntities);                
     }
     else
     {
         base.DeleteEntity(session, entity, entityEntry, isCascadeDeleteEnabled, persister, transientEntities);
     }
 }
        /// <summary>
        /// Perform the entity deletion.  Well, as with most operations, does not
        /// really perform it; just schedules an action/execution with the
        /// <see cref="T:NHibernate.Engine.ActionQueue" /> for execution during flush.
        /// </summary>
        /// <param name="session">The originating session</param>
        /// <param name="entity">The entity to delete</param>
        /// <param name="entityEntry">The entity's entry in the <see cref="T:NHibernate.ISession" /></param>
        /// <param name="isCascadeDeleteEnabled">Is delete cascading enabled?</param>
        /// <param name="persister">The entity persister.</param>
        /// <param name="transientEntities">A cache of already deleted entities.</param>
        protected override void DeleteEntity(IEventSource session, object entity, EntityEntry entityEntry, 
            bool isCascadeDeleteEnabled, IEntityPersister persister, ISet transientEntities)
        {
            if (entity is IPersistentEntity)
            {
                eventListenerHelper.OnDelete(entity);

                CascadeBeforeDelete(session, persister, entity, entityEntry, transientEntities);
                CascadeAfterDelete(session, persister, entity, transientEntities);
            }
            else
            {
                base.DeleteEntity(session, entity, entityEntry, isCascadeDeleteEnabled, persister, transientEntities);
            }
        }
示例#5
0
        protected override void DeleteEntity(IEventSource session, object entity, EntityEntry entityEntry,
            bool isCascadeDeleteEnabled, IEntityPersister persister, ISet<object> transientEntities)
        {
            var systemEntity = entity as SystemEntity;
            HttpContextBase context = CurrentRequestData.CurrentContext;
            if (systemEntity != null && !(context != null && context.IsSoftDeleteDisabled()))
            {
                systemEntity.IsDeleted = true;

                CascadeBeforeDelete(session, persister, systemEntity, entityEntry, transientEntities);
                CascadeAfterDelete(session, persister, systemEntity, transientEntities);
            }
            else
            {
                base.DeleteEntity(session, entity, entityEntry, isCascadeDeleteEnabled,
                    persister, transientEntities);
            }
        }
		public FlushEntityEvent(IEventSource source, object entity, EntityEntry entry)
			: base(source)
		{
			this.entity = entity;
			entityEntry = entry;
		}
 protected override void DeleteEntity(IEventSource session, object entity, EntityEntry entityEntry, bool isCascadeDeleteEnabled, NHibernate.Persister.Entity.IEntityPersister persister, Iesi.Collections.ISet transientEntities)
 {
     var entityBase = entity as EntityBase;
     if (entityBase != null)
         entityBase.IsDeleted = true;
 }
示例#8
0
        private static Task ProcessDereferencedCollectionAsync(IPersistentCollection coll, ISessionImplementor session, CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(Task.FromCanceled <object>(cancellationToken));
            }
            try
            {
                IPersistenceContext  persistenceContext = session.PersistenceContext;
                CollectionEntry      entry           = persistenceContext.GetCollectionEntry(coll);
                ICollectionPersister loadedPersister = entry.LoadedPersister;

                if (log.IsDebugEnabled() && loadedPersister != null)
                {
                    log.Debug("Collection dereferenced: {0}", MessageHelper.CollectionInfoString(loadedPersister, coll, entry.LoadedKey, session));
                }

                // do a check
                bool hasOrphanDelete = loadedPersister != null && loadedPersister.HasOrphanDelete;
                if (hasOrphanDelete)
                {
                    object ownerId = loadedPersister.OwnerEntityPersister.GetIdentifier(coll.Owner);
                    // TODO NH Different behavior
                    //if (ownerId == null)
                    //{
                    //  // the owning entity may have been deleted and its identifier unset due to
                    //  // identifier-rollback; in which case, try to look up its identifier from
                    //  // the persistence context
                    //  if (session.Factory.Settings.IsIdentifierRollbackEnabled)
                    //  {
                    //    EntityEntry ownerEntry = persistenceContext.GetEntry(coll.Owner);
                    //    if (ownerEntry != null)
                    //    {
                    //      ownerId = ownerEntry.Id;
                    //    }
                    //  }
                    //  if (ownerId == null)
                    //  {
                    //    throw new AssertionFailure("Unable to determine collection owner identifier for orphan-delete processing");
                    //  }
                    //}
                    EntityKey key   = session.GenerateEntityKey(ownerId, loadedPersister.OwnerEntityPersister);
                    object    owner = persistenceContext.GetEntity(key);
                    if (owner == null)
                    {
                        return(Task.FromException <object>(new AssertionFailure("collection owner not associated with session: " + loadedPersister.Role)));
                    }
                    EntityEntry e = persistenceContext.GetEntry(owner);
                    //only collections belonging to deleted entities are allowed to be dereferenced in the case of orphan delete
                    if (e != null && e.Status != Status.Deleted && e.Status != Status.Gone)
                    {
                        return(Task.FromException <object>(new HibernateException("A collection with cascade=\"all-delete-orphan\" was no longer referenced by the owning entity instance: " + loadedPersister.Role)));
                    }
                }

                // do the work
                entry.CurrentPersister = null;
                entry.CurrentKey       = null;
                return(PrepareCollectionForUpdateAsync(coll, entry, session.Factory, cancellationToken));
            }
            catch (System.Exception ex)
            {
                return(Task.FromException <object>(ex));
            }
        }
示例#9
0
        /// <summary> Cascade an action to the child or children</summary>
        private void CascadeProperty(object parent, object child, IType type, CascadeStyle style, string propertyName, object anything, bool isCascadeDeleteEnabled)
        {
            if (child != null)
            {
                if (type.IsAssociationType)
                {
                    IAssociationType associationType = (IAssociationType)type;
                    if (CascadeAssociationNow(associationType))
                    {
                        CascadeAssociation(parent, child, type, style, anything, isCascadeDeleteEnabled);
                    }
                }
                else if (type.IsComponentType)
                {
                    CascadeComponent(parent, child, (IAbstractComponentType)type, propertyName, anything);
                }
            }
            else
            {
                // potentially we need to handle orphan deletes for one-to-ones here...
                if (type.IsEntityType && ((EntityType)type).IsLogicalOneToOne())
                {
                    // We have a physical or logical one-to-one and from previous checks we know we
                    // have a null value.  See if the attribute cascade settings and action-type require
                    // orphan checking
                    if (style.HasOrphanDelete && action.DeleteOrphans)
                    {
                        // value is orphaned if loaded state for this property shows not null
                        // because it is currently null.
                        EntityEntry entry = eventSource.PersistenceContext.GetEntry(parent);
                        if (entry != null && entry.Status != Status.Saving)
                        {
                            EntityType entityType = (EntityType)type;
                            object     loadedValue;
                            if (componentPathStack.Count == 0)
                            {
                                // association defined on entity
                                loadedValue = entry.GetLoadedValue(propertyName);
                            }
                            else
                            {
                                // association defined on component
                                // todo : this is currently unsupported because of the fact that
                                // we do not know the loaded state of this value properly
                                // and doing so would be very difficult given how components and
                                // entities are loaded (and how 'loaded state' is put into the
                                // EntityEntry).  Solutions here are to either:
                                //	1) properly account for components as a 2-phase load construct
                                //  2) just assume the association was just now orphaned and
                                //     issue the orphan delete.  This would require a special
                                //     set of SQL statements though since we do not know the
                                //     orphaned value, something a delete with a subquery to
                                //     match the owner.
                                loadedValue = null;
                            }

                            if (loadedValue != null)
                            {
                                eventSource.Delete(entry.Persister.EntityName, loadedValue, false, null);
                            }
                        }
                    }
                }
            }
        }
示例#10
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(types[i].ResolveIdentifierAsync(value, session, entity, cancellationToken)).ConfigureAwait(false);
                }
            }

            foreach (var i in collectionToResolveIndexes)
            {
                hydratedState[i] = await(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);
            }
        }
示例#11
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>
        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);
            }
        }
示例#12
0
 private static bool UseMinimalPuts(ISessionImplementor session, EntityEntry entityEntry)
 {
     return((session.Factory.Settings.IsMinimalPutsEnabled && session.CacheMode != CacheMode.Refresh) ||
            (entityEntry.Persister.HasLazyProperties && entityEntry.LoadedWithLazyPropertiesUnfetched && entityEntry.Persister.IsLazyPropertiesCacheable));
 }
示例#13
0
            private bool IsInManagedState(object child, IEventSource session)
            {
                EntityEntry entry = session.PersistenceContext.GetEntry(child);

                return(entry != null && (entry.Status == Status.Loaded || entry.Status == Status.ReadOnly));
            }