상속: ISerializable
예제 #1
0
		protected override JoinType GetJoinType(IAssociationType type, FetchMode config, string path,
			string lhsTable, string[] lhsColumns, bool nullable, int currentDepth, CascadeStyle cascadeStyle)
		{
			if (translator.IsJoin(path))
			{
				return translator.GetJoinType(path);
			}
			else
			{
				if (translator.HasProjection)
				{
					return JoinType.None;
				}
				else
				{
					FetchMode fetchMode = translator.RootCriteria.GetFetchMode(path);
					if (IsDefaultFetchMode(fetchMode))
					{
						return base.GetJoinType(type, config, path, lhsTable, lhsColumns, nullable, currentDepth, cascadeStyle);
					}
					else
					{
						if (fetchMode == FetchMode.Join)
						{
							IsDuplicateAssociation(lhsTable, lhsColumns, type); //deliberately ignore return value!
							return GetJoinType(nullable, currentDepth);
						}
						else
						{
							return JoinType.None;
						}
					}
				}
			}
		}
		/// <summary>
		/// Constructs StandardProperty instances.
		/// </summary>
		/// <param name="name">The name by which the property can be referenced within
		/// its owner.</param>
		/// <param name="node">The node name to use for XML-based representation of this
		/// property.</param>
		/// <param name="type">The Hibernate Type of this property.</param>
		/// <param name="lazy">Should this property be handled lazily?</param>
		/// <param name="insertable">Is this property an insertable value?</param>
		/// <param name="updateable">Is this property an updateable value?</param>
		/// <param name="insertGenerated">Is this property generated in the database on insert?</param>
		/// <param name="updateGenerated">Is this property generated in the database on update?</param>
		/// <param name="nullable">Is this property a nullable value?</param>
		/// <param name="checkable">Is this property a checkable value?</param>
		/// <param name="versionable">Is this property a versionable value?</param>
		/// <param name="cascadeStyle">The cascade style for this property's value.</param>
		/// <param name="fetchMode">Any fetch mode defined for this property </param>
		public StandardProperty(
			String name,
			String node,
			IType type,
			bool lazy,
			bool insertable,
			bool updateable,
			bool insertGenerated,
			bool updateGenerated,
			bool nullable,
			bool checkable,
			bool versionable,
			CascadeStyle cascadeStyle,
			FetchMode? fetchMode)
			: base(name, node, type)
		{
			this.lazy = lazy;
			this.insertable = insertable;
			this.updateable = updateable;
			this.insertGenerated = insertGenerated;
			this.updateGenerated = updateGenerated;
			this.nullable = nullable;
			this.dirtyCheckable = checkable;
			this.versionable = versionable;
			this.cascadeStyle = cascadeStyle;
			this.fetchMode = fetchMode;
		}
예제 #3
0
		/// <summary>
		/// Disable outer join fetching if this loader obtains an
		/// upgrade lock mode
		/// </summary>
		protected override bool IsJoinedFetchEnabled(IAssociationType type, FetchMode config,
		                                             CascadeStyle cascadeStyle)
		{
			return lockMode.GreaterThan(LockMode.Read) ?
			       false :
			       base.IsJoinedFetchEnabled(type, config, cascadeStyle);
		}
예제 #4
0
        /// <summary>
        /// Cascade an action from the parent entity instance to all its children.  This
        /// form is typically called from within cascade actions.
        /// </summary>
        /// <param name="persister">The parent's entity persister </param>
        /// <param name="parent">The parent reference. </param>
        /// <param name="anything">
        /// Typically some form of cascade-local cache
        /// which is specific to each CascadingAction type
        /// </param>
        /// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param>
        public async Task CascadeOnAsync(IEntityPersister persister, object parent, object anything, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            if (persister.HasCascades || action.RequiresNoCascadeChecking)
            {
                log.Info("processing cascade " + action + " for: " + persister.EntityName);

                IType[]        types         = persister.PropertyTypes;
                CascadeStyle[] cascadeStyles = persister.PropertyCascadeStyles;
                bool           hasUninitializedLazyProperties = persister.HasUninitializedLazyProperties(parent);
                for (int i = 0; i < types.Length; i++)
                {
                    CascadeStyle style        = cascadeStyles[i];
                    string       propertyName = persister.PropertyNames[i];
                    if (hasUninitializedLazyProperties && persister.PropertyLaziness[i] && !action.PerformOnLazyProperty)
                    {
                        //do nothing to avoid a lazy property initialization
                        continue;
                    }

                    if (style.DoCascade(action))
                    {
                        await(CascadePropertyAsync(parent, persister.GetPropertyValue(parent, i), types[i], style, propertyName, anything, false, cancellationToken)).ConfigureAwait(false);
                    }
                    else if (action.RequiresNoCascadeChecking)
                    {
                        await(action.NoCascadeAsync(eventSource, persister.GetPropertyValue(parent, i), parent, persister, i, cancellationToken)).ConfigureAwait(false);
                    }
                }

                log.Info("done processing cascade " + action + " for: " + persister.EntityName);
            }
        }
예제 #5
0
        /// <summary>
        /// Cascade to the collection elements
        /// </summary>
        /// <param name="action"></param>
        /// <param name="style"></param>
        /// <param name="collectionType"></param>
        /// <param name="elemType"></param>
        /// <param name="child"></param>
        /// <param name="cascadeVia"></param>
        /// <param name="session"></param>
        /// <param name="anything"></param>
        private static void CascadeCollection(
            CascadingAction action,
            CascadeStyle style,
            PersistentCollectionType collectionType,
            IType elemType,
            object child,
            CascadePoint cascadeVia,
            ISessionImplementor session,
            object anything)
        {
            // cascade to current collection elements
            if (log.IsDebugEnabled)
            {
                log.Debug("cascading to collection: " + collectionType.Role);
            }
            ICollection iter = action.CascadableChildrenCollection(collectionType, child);

            foreach (object obj in iter)
            {
                Cascade(session, obj, elemType, action, style, cascadeVia, anything);
            }

            // handle oprhaned entities!!
            if (style.HasOrphanDelete && action.DeleteOrphans() && child is PersistentCollection)
            {
                // We can do the cast since orphan-delete does not apply to:
                // 1. newly instatiated collections
                // 2. arrays ( we can't track orphans for detached arrays)
                DeleteOrphans(child as PersistentCollection, session);
            }
        }
예제 #6
0
        /// <summary>
        /// Cascade an action from the parent entity instance to all its children.  This
        /// form is typically called from within cascade actions.
        /// </summary>
        /// <param name="persister">The parent's entity persister </param>
        /// <param name="parent">The parent reference. </param>
        /// <param name="anything">
        /// Typically some form of cascade-local cache
        /// which is specific to each CascadingAction type
        /// </param>
        public void CascadeOn(IEntityPersister persister, object parent, object anything)
        {
            if (persister.HasCascades || action.RequiresNoCascadeChecking)
            {
                log.Info("processing cascade {0} for: {1}", action, persister.EntityName);

                IType[]        types         = persister.PropertyTypes;
                CascadeStyle[] cascadeStyles = persister.PropertyCascadeStyles;
                bool           hasUninitializedLazyProperties = persister.HasUninitializedLazyProperties(parent);
                for (int i = 0; i < types.Length; i++)
                {
                    CascadeStyle style        = cascadeStyles[i];
                    string       propertyName = persister.PropertyNames[i];
                    if (hasUninitializedLazyProperties && persister.PropertyLaziness[i] && !action.PerformOnLazyProperty)
                    {
                        //do nothing to avoid a lazy property initialization
                        continue;
                    }

                    if (style.DoCascade(action))
                    {
                        CascadeProperty(parent, persister.GetPropertyValue(parent, i), types[i], style, propertyName, anything, false);
                    }
                    else if (action.RequiresNoCascadeChecking)
                    {
                        action.NoCascade(eventSource, persister.GetPropertyValue(parent, i), parent, persister, i);
                    }
                }

                log.Info("done processing cascade {0} for: {1}", action, persister.EntityName);
            }
        }
예제 #7
0
        /// <summary>
        /// Cascade an action to the child or children
        /// </summary>
        /// <param name="session"></param>
        /// <param name="child"></param>
        /// <param name="type"></param>
        /// <param name="action"></param>
        /// <param name="style"></param>
        /// <param name="cascadeTo"></param>
        /// <param name="anything"></param>
        private static void Cascade(
            ISessionImplementor session,
            object child,
            IType type,
            CascadingAction action,
            CascadeStyle style,
            CascadePoint cascadeTo,
            object anything)
        {
            if (child != null)
            {
                if (type.IsAssociationType)
                {
                    if ((( IAssociationType )type).ForeignKeyType.CascadeNow(cascadeTo))
                    {
                        if (type.IsEntityType || type.IsObjectType)
                        {
                            action.Cascade(session, child, anything);
                        }
                        else if (type.IsPersistentCollectionType)
                        {
                            CascadePoint cascadeVia;
                            if (cascadeTo == CascadePoint.CascadeAfterInsertBeforeDelete)
                            {
                                cascadeVia = CascadePoint.CascadeAfterInsertBeforeDeleteViaCollection;
                            }
                            else
                            {
                                cascadeVia = cascadeTo;
                            }
                            PersistentCollectionType pctype    = ( PersistentCollectionType )type;
                            ICollectionPersister     persister = session.Factory.GetCollectionPersister(pctype.Role);
                            IType elemType = persister.ElementType;

                            // cascade to current collection elements
                            if (elemType.IsEntityType || elemType.IsObjectType || elemType.IsComponentType)
                            {
                                CascadeCollection(action, style, pctype, elemType, child, cascadeVia, session, anything);
                            }
                        }
                    }
                }
                else if (type.IsComponentType)
                {
                    IAbstractComponentType ctype = (( IAbstractComponentType )type);
                    object[] children            = ctype.GetPropertyValues(child, session);
                    IType[]  types = ctype.Subtypes;
                    for (int i = 0; i < types.Length; i++)
                    {
                        CascadeStyle componentPropertyStyle = ctype.Cascade(i);
                        if (componentPropertyStyle.DoCascade(action))
                        {
                            Cascade(session, children[i], types[i], action, componentPropertyStyle, cascadeTo, anything);
                        }
                    }
                }
            }
        }
예제 #8
0
        /// <summary> Cascade an action to a to-one association or any type</summary>
        private void CascadeToOne(object child, IType type, CascadeStyle style, object anything, bool isCascadeDeleteEnabled)
        {
            string entityName = type.IsEntityType ? ((EntityType)type).GetAssociatedEntityName() : null;

            if (style.ReallyDoCascade(action))
            {
                //not really necessary, but good for consistency...
                action.Cascade(eventSource, child, entityName, anything, isCascadeDeleteEnabled);
            }
        }
예제 #9
0
 private void CascadeAssociation(object parent, object child, IType type, CascadeStyle style, object anything, bool isCascadeDeleteEnabled)
 {
     if (type.IsEntityType || type.IsAnyType)
     {
         CascadeToOne(parent, child, type, style, anything, isCascadeDeleteEnabled);
     }
     else if (type.IsCollectionType)
     {
         CascadeCollection(parent, child, style, anything, (CollectionType)type);
     }
 }
예제 #10
0
 private void CascadeComponent(object parent, object child, IAbstractComponentType componentType, object anything)
 {
     object[] children = componentType.GetPropertyValues(child, eventSource);
     IType[]  types    = componentType.Subtypes;
     for (int i = 0; i < types.Length; i++)
     {
         CascadeStyle componentPropertyStyle = componentType.GetCascadeStyle(i);
         if (componentPropertyStyle.DoCascade(action))
         {
             CascadeProperty(parent, children[i], types[i], componentPropertyStyle, anything, false);
         }
     }
 }
예제 #11
0
 private async Task CascadeComponentAsync(object parent, object child, IAbstractComponentType componentType, string componentPropertyName, object anything, CancellationToken cancellationToken)
 {
     cancellationToken.ThrowIfCancellationRequested();
     componentPathStack.Push(componentPropertyName);
     object[] children = await(componentType.GetPropertyValuesAsync(child, eventSource, cancellationToken)).ConfigureAwait(false);
     IType[]  types    = componentType.Subtypes;
     for (int i = 0; i < types.Length; i++)
     {
         CascadeStyle componentPropertyStyle = componentType.GetCascadeStyle(i);
         string       subPropertyName        = componentType.PropertyNames[i];
         if (componentPropertyStyle.DoCascade(action))
         {
             await(CascadePropertyAsync(parent, children[i], types[i], componentPropertyStyle, subPropertyName, anything, false, cancellationToken)).ConfigureAwait(false);
         }
     }
     componentPathStack.Pop();
 }
예제 #12
0
        /// <summary> Cascade an action to a to-one association or any type</summary>
        private void CascadeToOne(object parent, object child, IType type, CascadeStyle style, object anything, bool isCascadeDeleteEnabled)
        {
            string entityName = type.IsEntityType ? ((EntityType)type).GetAssociatedEntityName() : null;

            if (style.ReallyDoCascade(action))
            {
                //not really necessary, but good for consistency...
                eventSource.PersistenceContext.AddChildParent(child, parent);
                try
                {
                    action.Cascade(eventSource, child, entityName, anything, isCascadeDeleteEnabled);
                }
                finally
                {
                    eventSource.PersistenceContext.RemoveChildParent(child);
                }
            }
        }
예제 #13
0
 /// <summary> Cascade an action to the child or children</summary>
 private void CascadeProperty(object parent, object child, IType type, CascadeStyle style, 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, anything);
         }
     }
 }
예제 #14
0
		/// <summary>
		/// Constructs VersionProperty instances.
		/// </summary>
		/// <param name="name">The name by which the property can be referenced within
		/// its owner.</param>
		/// <param name="node">The node name to use for XML-based representation of this
		/// property.</param>
		/// <param name="type">The Hibernate Type of this property.</param>
		/// <param name="lazy">Should this property be handled lazily?</param>
		/// <param name="insertable">Is this property an insertable value?</param>
		/// <param name="updateable">Is this property an updateable value?</param>
		/// <param name="insertGenerated">Is this property generated in the database on insert?</param>
		/// <param name="updateGenerated">Is this property generated in the database on update?</param>
		/// <param name="nullable">Is this property a nullable value?</param>
		/// <param name="checkable">Is this property a checkable value?</param>
		/// <param name="versionable">Is this property a versionable value?</param>
		/// <param name="cascadeStyle">The cascade style for this property's value.</param>
		/// <param name="unsavedValue">The value which, if found as the value of
		/// this (i.e., the version) property, represents new (i.e., un-saved)
		/// instances of the owning entity.</param>
		public VersionProperty(
			string name,
			string node,
			IType type,
			bool lazy,
			bool insertable,
			bool updateable,
			bool insertGenerated,
			bool updateGenerated,
			bool nullable,
			bool checkable,
			bool versionable,
			CascadeStyle cascadeStyle,
			VersionValue unsavedValue)
			: base(
				name, node, type, lazy, insertable, updateable, insertGenerated, updateGenerated, nullable, checkable, versionable,
				cascadeStyle, null)
		{
			this.unsavedValue = unsavedValue;
		}
예제 #15
0
        /// <summary> Cascade an action to a collection</summary>
        private void CascadeCollection(object parent, object child, CascadeStyle style, object anything, CollectionType type)
        {
            ICollectionPersister persister = eventSource.Factory.GetCollectionPersister(type.Role);
            IType elemType = persister.ElementType;

            CascadePoint oldCascadeTo = point;

            if (point == CascadePoint.AfterInsertBeforeDelete)
            {
                point = CascadePoint.AfterInsertBeforeDeleteViaCollection;
            }

            //cascade to current collection elements
            if (elemType.IsEntityType || elemType.IsAnyType || elemType.IsComponentType)
            {
                CascadeCollectionElements(parent, child, type, style, elemType, anything, persister.CascadeDeleteEnabled);
            }

            point = oldCascadeTo;
        }
예제 #16
0
        /// <summary> Cascade an action to a collection</summary>
        private async Task CascadeCollectionAsync(object parent, object child, CascadeStyle style, object anything, CollectionType type, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            ICollectionPersister persister = eventSource.Factory.GetCollectionPersister(type.Role);
            IType elemType = persister.ElementType;

            CascadePoint oldCascadeTo = point;

            if (point == CascadePoint.AfterInsertBeforeDelete)
            {
                point = CascadePoint.AfterInsertBeforeDeleteViaCollection;
            }

            //cascade to current collection elements
            if (elemType.IsEntityType || elemType.IsAnyType || elemType.IsComponentType)
            {
                await(CascadeCollectionElementsAsync(parent, child, type, style, elemType, anything, persister.CascadeDeleteEnabled, cancellationToken)).ConfigureAwait(false);
            }

            point = oldCascadeTo;
        }
예제 #17
0
 /// <summary>
 /// Cascade an action from the parent object to all its children.
 /// </summary>
 /// <param name="session"></param>
 /// <param name="persister"></param>
 /// <param name="parent"></param>
 /// <param name="action"></param>
 /// <param name="cascadeTo"></param>
 /// <param name="anything"></param>
 public static void Cascade(ISessionImplementor session, IClassPersister persister, object parent, CascadingAction action, CascadePoint cascadeTo, object anything)
 {
     if (persister.HasCascades)
     {
         if (log.IsDebugEnabled)
         {
             log.Debug("processing cascades for: " + persister.ClassName);
         }
         IType[]        types         = persister.PropertyTypes;
         CascadeStyle[] cascadeStyles = persister.PropertyCascadeStyles;
         for (int i = 0; i < types.Length; i++)
         {
             CascadeStyle style = cascadeStyles[i];
             if (style.DoCascade(action))
             {
                 Cascade(session, persister.GetPropertyValue(parent, i), types[i], action, style, cascadeTo, anything);
             }
         }
         if (log.IsDebugEnabled)
         {
             log.Debug("done processing cascades for: " + persister.ClassName);
         }
     }
 }
예제 #18
0
		/// <summary>
		/// The superclass deliberately excludes collections
		/// </summary>
		protected override bool IsJoinedFetchEnabled(IAssociationType type, FetchMode config,
		                                             CascadeStyle cascadeStyle)
		{
			return IsJoinedFetchEnabledInMapping(config, type);
		}
예제 #19
0
        /// <summary> Cascade to the collection elements</summary>
        private void CascadeCollectionElements(object parent, object child, CollectionType collectionType, CascadeStyle style, IType elemType, object anything, bool isCascadeDeleteEnabled)
        {
            bool reallyDoCascade = style.ReallyDoCascade(action) &&
                                   child != CollectionType.UnfetchedCollection;

            if (reallyDoCascade)
            {
                log.Info("cascade {0} for collection: {1}", action, collectionType.Role);

                foreach (object o in action.GetCascadableChildrenIterator(eventSource, collectionType, child))
                {
                    CascadeProperty(parent, o, elemType, style, null, anything, isCascadeDeleteEnabled);
                }

                log.Info("done cascade {0} for collection: {1}", action, collectionType.Role);
            }

            var  childAsPersColl = child as IPersistentCollection;
            bool deleteOrphans   = style.HasOrphanDelete && action.DeleteOrphans && elemType.IsEntityType &&
                                   childAsPersColl != null;              //a newly instantiated collection can't have orphans

            if (deleteOrphans)
            {
                // handle orphaned entities!!
                log.Info("deleting orphans for collection: {0}", collectionType.Role);

                // we can do the cast since orphan-delete does not apply to:
                // 1. newly instantiated collections
                // 2. arrays (we can't track orphans for detached arrays)
                string entityName = collectionType.GetAssociatedEntityName(eventSource.Factory);
                DeleteOrphans(entityName, childAsPersColl);

                log.Info("done deleting orphans for collection: {0}", collectionType.Role);
            }
        }
예제 #20
0
		/// <summary> Cascade an action to a to-one association or any type</summary>
		private void CascadeToOne(object child, IType type, CascadeStyle style, object anything, bool isCascadeDeleteEnabled)
		{
			string entityName = type.IsEntityType ? ((EntityType)type).GetAssociatedEntityName() : null;
			if (style.ReallyDoCascade(action))
			{
				//not really necessary, but good for consistency...
				action.Cascade(eventSource, child, entityName, anything, isCascadeDeleteEnabled);
			}
		}
예제 #21
0
		/// <summary> Cascade an action to a collection</summary>
		private void CascadeCollection(object child, CascadeStyle style, object anything, CollectionType type)
		{
			ICollectionPersister persister = eventSource.Factory.GetCollectionPersister(type.Role);
			IType elemType = persister.ElementType;

			CascadePoint oldCascadeTo = point;
			if (point == CascadePoint.AfterInsertBeforeDelete)
				point = CascadePoint.AfterInsertBeforeDeleteViaCollection;

			//cascade to current collection elements
			if (elemType.IsEntityType || elemType.IsAnyType || elemType.IsComponentType)
				CascadeCollectionElements(child, type, style, elemType, anything, persister.CascadeDeleteEnabled);

			point = oldCascadeTo;
		}
예제 #22
0
		/// <summary> Cascade to the collection elements</summary>
		private void CascadeCollectionElements(object child, CollectionType collectionType, CascadeStyle style, IType elemType, object anything, bool isCascadeDeleteEnabled)
		{
			// we can't cascade to non-embedded elements
			bool embeddedElements = eventSource.EntityMode != EntityMode.Xml
			                        || ((EntityType) collectionType.GetElementType(eventSource.Factory)).IsEmbeddedInXML;

			bool reallyDoCascade = style.ReallyDoCascade(action) && embeddedElements
			                       && child != CollectionType.UnfetchedCollection;

			if (reallyDoCascade)
			{
				log.Info("cascade " + action + " for collection: " + collectionType.Role);

				foreach (object o in action.GetCascadableChildrenIterator(eventSource, collectionType, child))
					CascadeProperty(o, elemType, style, anything, isCascadeDeleteEnabled);

				log.Info("done cascade " + action + " for collection: " + collectionType.Role);
			}

			var childAsPersColl = child as IPersistentCollection;
			bool deleteOrphans = style.HasOrphanDelete && action.DeleteOrphans && elemType.IsEntityType
			                     && childAsPersColl != null; //a newly instantiated collection can't have orphans

			if (deleteOrphans)
			{
				// handle orphaned entities!!
				log.Info("deleting orphans for collection: " + collectionType.Role);

				// we can do the cast since orphan-delete does not apply to:
				// 1. newly instantiated collections
				// 2. arrays (we can't track orphans for detached arrays)
				string entityName = collectionType.GetAssociatedEntityName(eventSource.Factory);
				DeleteOrphans(entityName, childAsPersColl);

				log.Info("done deleting orphans for collection: " + collectionType.Role);
			}
		}
예제 #23
0
        /// <summary> Cascade an action to the child or children</summary>
        private Task CascadePropertyAsync(object parent, object child, IType type, CascadeStyle style, string propertyName, object anything, bool isCascadeDeleteEnabled, CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(Task.FromCanceled <object>(cancellationToken));
            }
            try
            {
                if (child != null)
                {
                    if (type.IsAssociationType)
                    {
                        IAssociationType associationType = (IAssociationType)type;
                        if (CascadeAssociationNow(associationType))
                        {
                            return(CascadeAssociationAsync(parent, child, type, style, anything, isCascadeDeleteEnabled, cancellationToken));
                        }
                    }
                    else if (type.IsComponentType)
                    {
                        return(CascadeComponentAsync(parent, child, (IAbstractComponentType)type, propertyName, anything, cancellationToken));
                    }
                }
                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.Any())
                                {
                                    // 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)
                                {
                                    return(eventSource.DeleteAsync(entry.Persister.EntityName, loadedValue, false, null, cancellationToken));
                                }
                            }
                        }
                    }
                }
                return(Task.CompletedTask);
            }
            catch (System.Exception ex)
            {
                return(Task.FromException <object>(ex));
            }
        }
예제 #24
0
        /// <summary> Cascade to the collection elements</summary>
        private async Task CascadeCollectionElementsAsync(object parent, object child, CollectionType collectionType, CascadeStyle style, IType elemType, object anything, bool isCascadeDeleteEnabled, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            bool reallyDoCascade = style.ReallyDoCascade(action) &&
                                   child != CollectionType.UnfetchedCollection;

            if (reallyDoCascade)
            {
                log.Info("cascade " + action + " for collection: " + collectionType.Role);

                foreach (object o in action.GetCascadableChildrenIterator(eventSource, collectionType, child))
                {
                    await(CascadePropertyAsync(parent, o, elemType, style, null, anything, isCascadeDeleteEnabled, cancellationToken)).ConfigureAwait(false);
                }

                log.Info("done cascade " + action + " for collection: " + collectionType.Role);
            }

            var  childAsPersColl = child as IPersistentCollection;
            bool deleteOrphans   = style.HasOrphanDelete && action.DeleteOrphans && elemType.IsEntityType &&
                                   childAsPersColl != null;              //a newly instantiated collection can't have orphans

            if (deleteOrphans)
            {
                // handle orphaned entities!!
                log.Info("deleting orphans for collection: " + collectionType.Role);

                // we can do the cast since orphan-delete does not apply to:
                // 1. newly instantiated collections
                // 2. arrays (we can't track orphans for detached arrays)
                string entityName = collectionType.GetAssociatedEntityName(eventSource.Factory);
                await(DeleteOrphansAsync(entityName, childAsPersColl, cancellationToken)).ConfigureAwait(false);

                log.Info("done deleting orphans for collection: " + collectionType.Role);
            }
        }
예제 #25
0
		/// <summary>
		/// Cascade an action to the child or children
		/// </summary>
		/// <param name="session"></param>
		/// <param name="child"></param>
		/// <param name="type"></param>
		/// <param name="action"></param>
		/// <param name="style"></param>
		/// <param name="cascadeTo"></param>
		/// <param name="anything"></param>
		private static void Cascade(
			ISessionImplementor session,
			object child,
			IType type,
			CascadingAction action,
			CascadeStyle style,
			CascadePoint cascadeTo,
			object anything)
		{
			if (child != null)
			{
				if (type.IsAssociationType)
				{
					if (((IAssociationType) type).ForeignKeyDirection.CascadeNow(cascadeTo))
					{
						if (type.IsEntityType || type.IsAnyType)
						{
							action.Cascade(session, child, anything);
						}
						else if (type.IsCollectionType)
						{
							CascadePoint cascadeVia;
							if (cascadeTo == CascadePoint.CascadeAfterInsertBeforeDelete)
							{
								cascadeVia = CascadePoint.CascadeAfterInsertBeforeDeleteViaCollection;
							}
							else
							{
								cascadeVia = cascadeTo;
							}
							CollectionType pctype = (CollectionType) type;
							ICollectionPersister persister = session.Factory.GetCollectionPersister(pctype.Role);
							IType elemType = persister.ElementType;

							// cascade to current collection elements
							if (elemType.IsEntityType || elemType.IsAnyType || elemType.IsComponentType)
							{
								CascadeCollection(action, style, pctype, elemType, child, cascadeVia, session, anything);
							}
						}
					}
				}
				else if (type.IsComponentType)
				{
					IAbstractComponentType ctype = ((IAbstractComponentType) type);
					object[] children = ctype.GetPropertyValues(child, session);
					IType[] types = ctype.Subtypes;
					for (int i = 0; i < types.Length; i++)
					{
						CascadeStyle componentPropertyStyle = ctype.GetCascadeStyle(i);
						if (componentPropertyStyle.DoCascade(action))
						{
							Cascade(session, children[i], types[i], action, componentPropertyStyle, cascadeTo, anything);
						}
					}
				}
			}
		}
예제 #26
0
		/// <summary>
		/// Cascade to the collection elements
		/// </summary>
		/// <param name="action"></param>
		/// <param name="style"></param>
		/// <param name="collectionType"></param>
		/// <param name="elemType"></param>
		/// <param name="child"></param>
		/// <param name="cascadeVia"></param>
		/// <param name="session"></param>
		/// <param name="anything"></param>
		private static void CascadeCollection(
			CascadingAction action,
			CascadeStyle style,
			CollectionType collectionType,
			IType elemType,
			object child,
			CascadePoint cascadeVia,
			ISessionImplementor session,
			object anything)
		{
			// cascade to current collection elements
			if (log.IsDebugEnabled)
			{
				log.Debug("cascading to collection: " + collectionType.Role);
			}
			ICollection iter = action.CascadableChildrenCollection(collectionType, child);
			foreach (object obj in iter)
			{
				Cascade(session, obj, elemType, action, style, cascadeVia, anything);
			}

			// handle oprhaned entities!!
			if (style.HasOrphanDelete && action.DeleteOrphans() && child is IPersistentCollection)
			{
				// We can do the cast since orphan-delete does not apply to:
				// 1. newly instatiated collections
				// 2. arrays ( we can't track orphans for detached arrays)
				System.Type entityName = collectionType.GetAssociatedClass(session.Factory);
				DeleteOrphans(entityName, child as IPersistentCollection, session);
			}
		}
예제 #27
0
		/// <summary>
		/// Get the join type (inner, outer, etc) or -1 if the
		/// association should not be joined. Override on
		/// subclasses.
		/// </summary>
		protected virtual JoinType GetJoinType(IAssociationType type, FetchMode config, string path, string lhsTable,
			string[] lhsColumns, bool nullable, int currentDepth, CascadeStyle cascadeStyle)
		{
			if (!IsJoinedFetchEnabled(type, config, cascadeStyle))
				return JoinType.None;

			if (IsTooDeep(currentDepth) || (type.IsCollectionType && IsTooManyCollections))
				return JoinType.None;

			bool dupe = IsDuplicateAssociation(lhsTable, lhsColumns, type);
			if (dupe)
				return JoinType.None;

			return GetJoinType(nullable, currentDepth);
		}
예제 #28
0
 private Task CascadeAssociationAsync(object parent, object child, IType type, CascadeStyle style, object anything, bool isCascadeDeleteEnabled, CancellationToken cancellationToken)
 {
     if (cancellationToken.IsCancellationRequested)
     {
         return(Task.FromCanceled <object>(cancellationToken));
     }
     try
     {
         if (type.IsEntityType || type.IsAnyType)
         {
             return(CascadeToOneAsync(parent, child, type, style, anything, isCascadeDeleteEnabled, cancellationToken));
         }
         else if (type.IsCollectionType)
         {
             return(CascadeCollectionAsync(parent, child, style, anything, (CollectionType)type, cancellationToken));
         }
         return(Task.CompletedTask);
     }
     catch (System.Exception ex)
     {
         return(Task.FromException <object>(ex));
     }
 }
예제 #29
0
		/// <summary> Cascade an action to the child or children</summary>
		private void CascadeProperty(object child, IType type, CascadeStyle style, object anything, bool isCascadeDeleteEnabled)
		{
			if (child != null)
			{
				if (type.IsAssociationType)
				{
					IAssociationType associationType = (IAssociationType)type;
					if (CascadeAssociationNow(associationType))
					{
						CascadeAssociation(child, type, style, anything, isCascadeDeleteEnabled);
					}
				}
				else if (type.IsComponentType)
				{
					CascadeComponent(child, (IAbstractComponentType)type, anything);
				}
			}
		}
예제 #30
0
        /// <summary> Cascade an action to a to-one association or any type</summary>
        private async Task CascadeToOneAsync(object parent, object child, IType type, CascadeStyle style, object anything, bool isCascadeDeleteEnabled, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            string entityName = type.IsEntityType ? ((EntityType)type).GetAssociatedEntityName() : null;

            if (style.ReallyDoCascade(action))
            {
                //not really necessary, but good for consistency...
                eventSource.PersistenceContext.AddChildParent(child, parent);
                try
                {
                    await(action.CascadeAsync(eventSource, child, entityName, anything, isCascadeDeleteEnabled, cancellationToken)).ConfigureAwait(false);
                }
                finally
                {
                    eventSource.PersistenceContext.RemoveChildParent(child);
                }
            }
        }
예제 #31
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)
                        {
                            object loadedValue;
                            if (componentPathStack.Count == 0)
                            {
                                // association defined on entity
                                loadedValue = entry.GetLoadedValue(propertyName);

                                // Check this is not a null carrying proxy. The no-proxy load is currently handled by
                                // putting a proxy (!) flagged for unwrapping (even for non-constrained one-to-one,
                                // which association may be null) in the loadedState of the parent. The unwrap flag
                                // causes it to support having a null implementation, instead of throwing an entity
                                // not found error.
                                loadedValue = eventSource.PersistenceContext.UnproxyAndReassociate(loadedValue);
                            }
                            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);
                            }
                        }
                    }
                }
            }
        }
예제 #32
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.Any())
							{
								// 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);
							}
						}
					}
				}
			}
		}
예제 #33
0
		/// <summary> Cascade an action to a to-one association or any type</summary>
		private void CascadeToOne(object parent, object child, IType type, CascadeStyle style, object anything, bool isCascadeDeleteEnabled)
		{
			string entityName = type.IsEntityType ? ((EntityType)type).GetAssociatedEntityName() : null;
			if (style.ReallyDoCascade(action))
			{
				//not really necessary, but good for consistency...
				eventSource.PersistenceContext.AddChildParent(child, parent);
				try
				{
					action.Cascade(eventSource, child, entityName, anything, isCascadeDeleteEnabled);
				}
				finally
				{
					eventSource.PersistenceContext.RemoveChildParent(child);
				}
			}
		}
예제 #34
0
			public MultipleCascadeStyle(CascadeStyle[] styles)
			{
				this.styles = styles;
			}
예제 #35
0
		private void CascadeAssociation(object child, IType type, CascadeStyle style, object anything, bool isCascadeDeleteEnabled)
		{
			if (type.IsEntityType || type.IsAnyType)
			{
				CascadeToOne(child, type, style, anything, isCascadeDeleteEnabled);
			}
			else if (type.IsCollectionType)
			{
				CascadeCollection(child, style, anything, (CollectionType)type);
			}
		}
예제 #36
0
		/// <summary>
		/// Override on subclasses to enable or suppress joining
		/// of certain association types
		/// </summary>
		protected virtual bool IsJoinedFetchEnabled(IAssociationType type, FetchMode config,
																								CascadeStyle cascadeStyle)
		{
			return type.IsEntityType && IsJoinedFetchEnabledInMapping(config, type);
		}
		protected override bool IsJoinedFetchEnabled(IAssociationType type, FetchMode config, CascadeStyle cascadeStyle)
		{
			return
				(type.IsEntityType || type.IsCollectionType) && (cascadeStyle == null || cascadeStyle.DoCascade(cascadeAction));
		}