Exemple #1
0
 /// <summary>
 /// Initializes a new instance of <see cref="CollectionEntry"/>.
 /// </summary>
 /// <param name="cs">The <see cref="ICollectionSnapshot"/> from another <see cref="ISession"/>.</param>
 /// <param name="factory">The <see cref="ISessionFactoryImplementor"/> that created this <see cref="ISession"/>.</param>
 /// <remarks>
 /// This takes an <see cref="ICollectionSnapshot"/> from another <see cref="ISession"/> and
 /// creates an entry for it in this <see cref="ISession"/> by copying the values from the
 /// <c>cs</c> parameter.
 /// </remarks>
 public CollectionEntry(ICollectionSnapshot cs, ISessionFactoryImplementor factory)
 {
     this.dirty       = cs.Dirty;
     this.snapshot    = cs.Snapshot;
     this.loadedKey   = cs.Key;
     this.initialized = true;
     // Detached collections that get found and reattached during flush
     // shouldn't be ignored
     this.ignore = false;
     SetLoadedPersister(factory.GetCollectionPersister(cs.Role));
 }
Exemple #2
0
        /// <summary> 
        /// Reattach a detached (disassociated) initialized or uninitialized
        /// collection wrapper, using a snapshot carried with the collection wrapper
        /// </summary>
        protected internal void ReattachCollection(IPersistentCollection collection, ICollectionSnapshot snapshot)
        {
            if (collection.WasInitialized)
            {
                Session.PersistenceContext.AddInitializedDetachedCollection(collection, snapshot);
            }
            else
            {
                if (!IsCollectionSnapshotValid(snapshot))
                    throw new HibernateException("could not reassociate uninitialized transient collection");

                Session.PersistenceContext.AddUninitializedDetachedCollection(collection, snapshot);
            }
        }
Exemple #3
0
        protected override object ProcessCollection(object collection, PersistentCollectionType type)
        {
            ICollectionPersister persister = Session.GetCollectionPersister(type.Role);

            if (collection == null)
            {
                // Do nothing
            }
            else if (collection is PersistentCollection)
            {
                PersistentCollection coll = (PersistentCollection)collection;

                if (coll.SetCurrentSession(Session))
                {
                    ICollectionSnapshot snapshot = coll.CollectionSnapshot;
                    if (SessionImpl.IsOwnerUnchanged(snapshot, persister, this.Key))
                    {
                        // a "detached" collection that originally belonged to the same entity
                        if (snapshot.Dirty)
                        {
                            throw new HibernateException("reassociated object has dirty collection");
                        }
                        Session.ReattachCollection(coll, snapshot);
                    }
                    else
                    {
                        // a "detached" collection that belonged to a different entity
                        throw new HibernateException("reassociated object has dirty collection reference");
                    }
                }
                else
                {
                    // a collection loaded in the current session
                    // can not possibly be the collection belonging
                    // to the entity passed to update()
                    throw new HibernateException("reassociated object has dirty collection reference");
                }
            }
            else
            {
                // brand new collection
                //TODO: or an array!! we can't lock objects with arrays now??
                throw new HibernateException("reassociated object has dirty collection reference");
            }

            return(null);
        }
Exemple #4
0
        protected override object ProcessCollection(object collection, PersistentCollectionType type)
        {
            ICollectionPersister persister = Session.GetCollectionPersister(type.Role);

            if (collection is PersistentCollection)
            {
                PersistentCollection wrapper = (PersistentCollection)collection;

                if (wrapper.SetCurrentSession(Session))
                {
                    //a "detached" collection!
                    ICollectionSnapshot snapshot = wrapper.CollectionSnapshot;

                    if (!SessionImpl.IsOwnerUnchanged(snapshot, persister, Key))
                    {
                        // if the collection belonged to a different entity,
                        // clean up the existing state of the collection
                        Session.RemoveCollection(persister, Key);
                    }

                    Session.ReattachCollection(wrapper, snapshot);
                }
                else
                {
                    // a collection loaded in the current session
                    // can not possibly be the collection belonging
                    // to the entity passed to update()
                    Session.RemoveCollection(persister, Key);
                }
            }
            else
            {
                // null or brand new collection
                // this will also (inefficiently) handle arrays, which have
                // no snapshot, so we can't do any better
                Session.RemoveCollection(persister, Key);
                //processArrayOrNewCollection(collection, type);
            }

            return(null);
        }
Exemple #5
0
 private static bool IsCollectionSnapshotValid(ICollectionSnapshot snapshot)
 {
     return snapshot != null &&
              snapshot.Role != null &&
              snapshot.Key != null;
 }
Exemple #6
0
 /// <summary> 
 /// Has the owner of the collection changed since the collection was snapshotted and detached?
 /// </summary>
 protected internal static bool IsOwnerUnchanged(ICollectionSnapshot snapshot, ICollectionPersister persister, object id)
 {
     return IsCollectionSnapshotValid(snapshot) &&
              persister.Role.Equals(snapshot.Role) &&
              id.Equals(snapshot.Key);
 }
		/// <summary>
		/// Initializes a new instance of <see cref="CollectionEntry"/>. 
		/// </summary>
		/// <param name="cs">The <see cref="ICollectionSnapshot"/> from another <see cref="ISession"/>.</param>
		/// <param name="factory">The <see cref="ISessionFactoryImplementor"/> that created this <see cref="ISession"/>.</param>
		/// <remarks>
		/// This takes an <see cref="ICollectionSnapshot"/> from another <see cref="ISession"/> and 
		/// creates an entry for it in this <see cref="ISession"/> by copying the values from the 
		/// <c>cs</c> parameter.
		/// </remarks>
		public CollectionEntry( ICollectionSnapshot cs, ISessionFactoryImplementor factory )
		{
			this.dirty = cs.Dirty;
			this.snapshot = cs.Snapshot;
			this.loadedKey = cs.Key;
			this.initialized = true;
			// Detached collections that get found and reattached during flush
			// shouldn't be ignored
			this.ignore = false;
			SetLoadedPersister( factory.GetCollectionPersister( cs.Role ) );
		}
 /// <summary> add a detached uninitialized collection</summary>
 public void AddUninitializedDetachedCollection(IPersistentCollection collection, ICollectionSnapshot snapshot)
 {
     CollectionEntry ce = new CollectionEntry(snapshot, Session.Factory);
     collection.CollectionSnapshot = ce; // NH Different behavior
     AddCollection(collection, ce, ce.Key);
 }
 /// <summary> 
 /// add an (initialized) collection that was created by another session and passed
 /// into update() (ie. one with a snapshot and existing state on the database)
 /// </summary>
 public void AddInitializedDetachedCollection(IPersistentCollection collection,
     ICollectionSnapshot snapshot)
 {
     if (snapshot.WasDereferenced)
     {
         //treat it just like a new collection
         AddCollection(collection);
     }
     else
     {
         CollectionEntry ce = new CollectionEntry(snapshot, session.Factory);
         collection.CollectionSnapshot = ce; // NH Different behavior
         AddCollection(collection, ce, ce.Key);
     }
 }
		/// <summary>
		/// Add an (initialized) collection that was created by another session and passed
		/// into update() (i.e. one with a snapshot and existing state on the database)
		/// </summary>
		/// <param name="collection"></param>
		/// <param name="cs"></param>
		private void AddInitializedDetachedCollection( PersistentCollection collection, ICollectionSnapshot cs )
		{
			if( cs.WasDereferenced )
			{
				AddCollection( collection );
			}
			else
			{
				CollectionEntry ce = new CollectionEntry( cs, factory );
				collection.CollectionSnapshot = ce;
				AddCollection( collection, ce, cs.Key );
			}
		}
		/// <summary>
		/// Reattach a detached (disassociated) initialized or uninitialized collection wrapper
		/// </summary>
		/// <param name="collection"></param>
		/// <param name="snapshot"></param>
		internal void ReattachCollection( PersistentCollection collection, ICollectionSnapshot snapshot )
		{
			if( collection.WasInitialized )
			{
				AddInitializedDetachedCollection( collection, snapshot );
			}
			else
			{
				if( !IsCollectionSnapshotValid( snapshot ) )
				{
					throw new HibernateException( "could not reassociate uninitialized transient collection" );
				}
				AddUninitializedDetachedCollection(
					collection,
					GetCollectionPersister( snapshot.Role ),
					snapshot.Key );
			}
		}