Example #1
0
 public CollectionUpdateAction(
     IPersistentCollection collection, ICollectionPersister persister,
     object key, bool emptySnapshot, ISessionImplementor session)
     : base(persister, collection, key, session)
 {
     this.emptySnapshot = emptySnapshot;
 }
		public override object ReadFrom(IDataReader reader, ICollectionPersister role, ICollectionAliases descriptor,
		                                object owner)
		{
			object element = role.ReadElement(reader, owner, descriptor.SuffixedElementAliases, Session);
			bag.Add(element);
			return element;
		}
		protected override object CopyElement(ICollectionPersister persister, object element, ISessionImplementor session, object owner, IDictionary copiedAlready)
		{
			DictionaryEntry de = ( DictionaryEntry ) element;
			return new DictionaryEntry(
				persister.IndexType.Copy( de.Key, null, session, owner, copiedAlready ),
				persister.ElementType.Copy( de.Value, null, session, owner, copiedAlready ) );
		}
		/// <summary>
		/// Initializes a new instance of <see cref="ScheduledCollectionUpdate"/>.
		/// </summary>
		/// <param name="collection">The <see cref="IPersistentCollection"/> to update.</param>
		/// <param name="persister">The <see cref="ICollectionPersister"/> that is responsible for the persisting the Collection.</param>
		/// <param name="id">The identifier of the Collection owner.</param>
		/// <param name="emptySnapshot">Indicates if the Collection was empty when it was loaded.</param>
		/// <param name="session">The <see cref="ISessionImplementor"/> that the Action is occuring in.</param>
		public ScheduledCollectionUpdate(IPersistentCollection collection, ICollectionPersister persister, object id,
		                                 bool emptySnapshot, ISessionImplementor session)
			: base(persister, id, session)
		{
			_collection = collection;
			_emptySnapshot = emptySnapshot;
		}
		/// <summary>
		/// Initializes a new instance of <see cref="ScheduledCollectionAction"/>.
		/// </summary>
		/// <param name="persister">The <see cref="ICollectionPersister"/> that is responsible for the persisting the Collection.</param>
		/// <param name="id">The identifier of the Collection owner.</param>
		/// <param name="session">The <see cref="ISessionImplementor"/> that the Action is occuring in.</param>
		public ScheduledCollectionAction(ICollectionPersister persister, object id, ISessionImplementor session)
		{
			this.persister = persister;
			this.session = session;
			this.id = id;
			this.collectionRole = persister.Role;
		}
Example #6
0
		public LoadingCollectionEntry(IDataReader resultSet, ICollectionPersister persister, object key, IPersistentCollection collection)
		{
			this.resultSet = resultSet;
			this.persister = persister;
			this.key = key;
			this.collection = collection;
		}
		/// <summary> Try to initialize a collection from the cache</summary>
		private bool InitializeCollectionFromCache(object id, ICollectionPersister persister, IPersistentCollection collection, ISessionImplementor source)
		{

			if (!(source.EnabledFilters.Count == 0) && persister.IsAffectedByEnabledFilters(source))
			{
				log.Debug("disregarding cached version (if any) of collection due to enabled filters ");
				return false;
			}

			bool useCache = persister.HasCache && ((source.CacheMode & CacheMode.Get) == CacheMode.Get);

			if (!useCache)
			{
				return false;
			}
			else
			{
				ISessionFactoryImplementor factory = source.Factory;

				CacheKey ck = new CacheKey(id, persister.KeyType, persister.Role, source.EntityMode, factory);
				object ce = persister.Cache.Get(ck, source.Timestamp);

				if (factory.Statistics.IsStatisticsEnabled)
				{
					if (ce == null)
					{
						factory.StatisticsImplementor.SecondLevelCacheMiss(persister.Cache.RegionName);
					}
					else
					{
						factory.StatisticsImplementor.SecondLevelCacheHit(persister.Cache.RegionName);
					}
				}

				if (ce == null)
				{
					log.DebugFormat("Collection cache miss: {0}", ck);
				}
				else
				{
					log.DebugFormat("Collection cache hit: {0}", ck);
				}

				if (ce == null)
				{
					return false;
				}
				else
				{
					IPersistenceContext persistenceContext = source.PersistenceContext;

					CollectionCacheEntry cacheEntry = (CollectionCacheEntry)persister.CacheEntryStructure.Destructure(ce, factory);
					cacheEntry.Assemble(collection, persister, persistenceContext.GetCollectionOwner(id, persister));

					persistenceContext.GetCollectionEntry(collection).PostInitialize(collection);
					return true;
				}
			}
		}
		/// <summary> 
		/// Schedules a collection for deletion. 
		/// </summary>
		/// <param name="role">The persister representing the collection to be removed. </param>
		/// <param name="collectionKey">The collection key (differs from owner-id in the case of property-refs). </param>
		/// <param name="source">The session from which the request originated. </param>
		internal void RemoveCollection(ICollectionPersister role, object collectionKey, IEventSource source)
		{
			if (log.IsDebugEnabled)
			{
				log.Debug("collection dereferenced while transient " + MessageHelper.CollectionInfoString(role, ownerIdentifier, source.Factory));
			}
			source.ActionQueue.AddAction(new CollectionRemoveAction(owner, role, collectionKey, false, source));
		}
		/// <summary> Constructs an AbstractCollectionEvent object. </summary>
		/// <param name="collectionPersister">The collection persister.</param>
		/// <param name="collection">The collection </param>
		/// <param name="source">The Session source </param>
		/// <param name="affectedOwner">The owner that is affected by this event; can be null if unavailable </param>
		/// <param name="affectedOwnerId">
		/// The ID for the owner that is affected by this event; can be null if unavailable
		/// that is affected by this event; can be null if unavailable
		/// </param>
		protected AbstractCollectionEvent(ICollectionPersister collectionPersister, IPersistentCollection collection,
		                               IEventSource source, object affectedOwner, object affectedOwnerId) : base(source)
		{
			this.collection = collection;
			this.affectedOwner = affectedOwner;
			this.affectedOwnerId = affectedOwnerId;
			affectedOwnerEntityName = GetAffectedOwnerEntityName(collectionPersister, affectedOwner, source);
		}
		public BatchingCollectionInitializer( ICollectionPersister collPersister, int batchSize, Loader batchLoader, int smallBatchSize, Loader smallBatchLoader, Loader nonBatchLoader )
		{
			this.batchLoader = batchLoader;
			this.nonBatchLoader = nonBatchLoader;
			this.batchSize = batchSize;
			this.collectionPersister = collPersister;
			this.smallBatchLoader = smallBatchLoader;
			this.smallBatchSize = smallBatchSize;
		}
Example #11
0
		protected override ICollection Snapshot(ICollectionPersister persister)
		{
			Hashtable clonedMap = new Hashtable(map.Count);
			foreach (DictionaryEntry e in map)
			{
				clonedMap[e.Key] = persister.ElementType.DeepCopy(e.Value, EntityMode.Poco, persister.Factory);
			}
			return clonedMap;
		}
 public BatchingCollectionInitializer(
     ICollectionPersister collectionPersister,
     int[] batchSizes,
     Loader[] loaders)
 {
     this.loaders = loaders;
     this.batchSizes = batchSizes;
     this.collectionPersister = collectionPersister;
 }
		/// <summary>
		/// 
		/// </summary>
		/// <param name="persister"></param>
		/// <returns></returns>
		protected override ICollection Snapshot( ICollectionPersister persister )
		{
			ArrayList clonedList = new ArrayList( list.Count );
			foreach( object obj in list )
			{
				clonedList.Add( persister.ElementType.DeepCopy( obj ) );
			}
			return clonedList;
		}
Example #14
0
        /// <summary> 
        /// Finish the process of collection-loading for this bound result set.  Mainly this
        /// involves cleaning up resources and notifying the collections that loading is
        /// complete. 
        /// </summary>
        /// <param name="persister">The persister for which to complete loading. </param>
        public void EndLoadingCollections(ICollectionPersister persister)
        {
            if (!loadContexts.HasLoadingCollectionEntries || (localLoadingCollectionKeys.Count == 0))
            {
                return;
            }

            // in an effort to avoid concurrent-modification-exceptions (from
            // potential recursive calls back through here as a result of the
            // eventual call to PersistentCollection#endRead), we scan the
            // internal loadingCollections map for matches and store those matches
            // in a temp collection.  the temp collection is then used to "drive"
            // the #endRead processing.
            List<CollectionKey> toRemove = new List<CollectionKey>();
            List<LoadingCollectionEntry> matches =new List<LoadingCollectionEntry>();
            foreach (CollectionKey collectionKey in localLoadingCollectionKeys)
            {
                ISessionImplementor session = LoadContext.PersistenceContext.Session;

                LoadingCollectionEntry lce = loadContexts.LocateLoadingCollectionEntry(collectionKey);
                if (lce == null)
                {
                    log.Warn("In CollectionLoadContext#endLoadingCollections, localLoadingCollectionKeys contained [" + collectionKey + "], but no LoadingCollectionEntry was found in loadContexts");
                }
                else if (lce.ResultSet == resultSet && lce.Persister == persister)
                {
                    matches.Add(lce);
                    if (lce.Collection.Owner == null)
                    {
                        session.PersistenceContext.AddUnownedCollection(new CollectionKey(persister, lce.Key, session.EntityMode),
                                                                        lce.Collection);
                    }
                    if (log.IsDebugEnabled)
                    {
                        log.Debug("removing collection load entry [" + lce + "]");
                    }

                    // todo : i'd much rather have this done from #endLoadingCollection(CollectionPersister,LoadingCollectionEntry)...
                    loadContexts.UnregisterLoadingCollectionXRef(collectionKey);
                    toRemove.Add(collectionKey);
                }
            }
            localLoadingCollectionKeys.RemoveAll(toRemove);

            EndLoadingCollections(persister, matches);
            if ((localLoadingCollectionKeys.Count == 0))
            {
                // todo : hack!!!
                // NOTE : here we cleanup the load context when we have no more local
                // LCE entries.  This "works" for the time being because really
                // only the collection load contexts are implemented.  Long term,
                // this cleanup should become part of the "close result set"
                // processing from the (sandbox/jdbc) jdbc-container code.
                loadContexts.Cleanup(resultSet);
            }
        }
		public object ReplaceElements(object original, object target, ICollectionPersister persister, object owner, IDictionary copyCache, ISessionImplementor session)
		{
			IDefaultableList result = (IDefaultableList)target;
			result.Clear();
			foreach (object o in (IDefaultableList)original)
			{
				result.Add(o);
			}
			return result;
		}
		/// <summary> 
		/// Removes a persistent collection from a specified owner. 
		/// </summary>
		/// <param name="affectedOwner">The collection's owner; must be non-null </param>
		/// <param name="persister"> The collection's persister </param>
		/// <param name="id">The collection key </param>
		/// <param name="emptySnapshot">Indicates if the snapshot is empty </param>
		/// <param name="session">The session </param>
		/// <remarks> Use this constructor when the collection to be removed has not been loaded. </remarks>
		public CollectionRemoveAction(object affectedOwner, ICollectionPersister persister, object id, bool emptySnapshot,
		                              ISessionImplementor session) : base(persister, null, id, session)
		{
			if (affectedOwner == null)
			{
				throw new AssertionFailure("affectedOwner == null");
			}
			this.emptySnapshot = emptySnapshot;
			this.affectedOwner = affectedOwner;
		}
		/// <summary>
		/// Returns a Hashtable where the Key &amp; the Value are both a Copy of the
		/// same object.
		/// <see cref="AbstractPersistentCollection.Snapshot(ICollectionPersister)"/>
		/// </summary>
		/// <param name="persister"></param>
		protected override ICollection Snapshot(ICollectionPersister persister)
		{
			Hashtable clonedMap = new Hashtable(internalSet.Count);
			foreach (object obj in internalSet)
			{
				object copied = persister.ElementType.DeepCopy(obj);
				clonedMap[copied] = copied;
			}
			return clonedMap;
		}
		protected void InitClassPersisters( IList associations )
		{
			int joins = CountClassPersisters( associations );

			collectionOwner = -1; // if no collection found
			classPersisters = new ILoadable[ joins + 1 ];
			Owners = new int[ joins + 1 ];
			aliases = new string[ joins + 1 ];
			lockModeArray = CreateLockModeArray( joins + 1, LockMode.None );
			int i = 0;
			foreach( OuterJoinableAssociation oj in associations )
			{
				object subpersister = oj.Joinable;
				if( subpersister is ILoadable )
				{
					classPersisters[ i ] = ( ILoadable ) subpersister;
					Owners[ i ] = ToOwner( oj, joins, oj.IsOneToOne );
					aliases[ i ] = oj.Subalias;
					if( oj.JoinType == JoinType.InnerJoin )
					{
						AddAllToPropertySpaces( classPersisters[ i ].PropertySpaces );
					}
					i++;
				}
				else
				{
					IQueryableCollection collPersister = ( IQueryableCollection ) subpersister;
					// TODO: ?? suppress initialization of collections with a where condition
					if( oj.JoinType == JoinType.LeftOuterJoin )
					{
						collectionPersister = collPersister;
						collectionOwner = ToOwner( oj, joins, true );
					}
					else
					{
						AddToPropertySpaces( collPersister.CollectionSpace );
					}

					if( collPersister.IsOneToMany )
					{
						classPersisters[ i ] = ( ILoadable ) collPersister.ElementPersister;
						aliases[ i ] = oj.Subalias;
						i++;
					}
				}
			}
			classPersisters[ joins ] = persister;
			Owners[ joins ] = -1;
			aliases[ joins ] = alias;

			if( ArrayHelper.IsAllNegative( Owners ) )
			{
				Owners = null;
			}
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="persister"></param>
		/// <returns></returns>
		protected override ICollection Snapshot( ICollectionPersister persister )
		{
			SortedList clonedMap = new SortedList( comparer );
			foreach( DictionaryEntry de in map )
			{
				object copy = persister.ElementType.DeepCopy( de.Value );
				clonedMap.Add( de.Key, copy );
			}

			return clonedMap;
		}
Example #20
0
		public object ReplaceElements(object original, object target, ICollectionPersister persister, object owner,
		                              IDictionary copyCache, ISessionImplementor session)
		{
			IList<Email> result = (IList<Email>) target;
			result.Clear();

			foreach (object o in ((IEnumerable) original))
				result.Add((Email) o);

			return result;
		}
		public override ICollection GetSnapshot(ICollectionPersister persister)
		{
			EntityMode entityMode = Session.EntityMode;
			Hashtable clonedMap = new Hashtable(map.Count);
			foreach (DictionaryEntry e in map)
			{
				object copy = persister.ElementType.DeepCopy(e.Value, entityMode, persister.Factory);
				clonedMap[e.Key] = copy;
			}
			return clonedMap;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="persister"></param>
		/// <returns></returns>
		protected override ICollection Snapshot( ICollectionPersister persister )
		{
			SortedList clonedSet = new SortedList( comparer, internalSet.Count );
			foreach( object obj in internalSet )
			{
				object copy = persister.ElementType.DeepCopy( obj );
				clonedSet.Add( copy, copy );
			}

			return clonedSet;
		}
		void IDeserializationCallback.OnDeserialization(object sender)
		{
			try
			{
				persister = session.Factory.GetCollectionPersister(collectionRole);
			}
			catch (MappingException e)
			{
				throw new IOException("Unable to resolve collection persister on deserialization", e);
			}
		}
Example #24
0
		/// <summary>
		/// Return a new snapshot of the current state.
		/// </summary>
		/// <param name="persister">The <see cref="ICollectionPersister"/> for this Collection.</param>
		/// <returns>
		/// A new <see cref="ArrayList"/> that contains Deep Copies of the 
		/// Elements stored in this wrapped collection.
		/// </returns>
		protected override ICollection Snapshot(ICollectionPersister persister)
		{
			EntityMode entityMode = Session.EntityMode;

			ArrayList clonedList = new ArrayList(list.Count);
			foreach (object obj in list)
			{
				clonedList.Add(persister.ElementType.DeepCopy(obj,entityMode, persister.Factory));
			}
			return clonedList;
		}
		/// <summary> 
		/// This version is slightly different in that here we need to assume that
		/// the owner is not yet associated with the session, and thus we cannot
		/// rely on the owner's EntityEntry snapshot... 
		/// </summary>
		/// <param name="role">The persister for the collection role being processed. </param>
		/// <returns> </returns>
		internal object ExtractCollectionKeyFromOwner(ICollectionPersister role)
		{
			if (role.CollectionType.UseLHSPrimaryKey)
			{
				return ownerIdentifier;
			}
			else
			{
				return role.OwnerEntityPersister.GetPropertyValue(owner, role.CollectionType.LHSPropertyName, Session.EntityMode);
			}
		}
		/// <summary>
		/// Initializes this Bag from the cached values.
		/// </summary>
		/// <param name="persister">The CollectionPersister to use to reassemble the PersistentIdentifierBag.</param>
		/// <param name="disassembled">The disassembled PersistentIdentifierBag.</param>
		/// <param name="owner">The owner object.</param>
		public override void InitializeFromCache(ICollectionPersister persister, object disassembled, object owner)
		{
			object[] array = (object[]) disassembled;
			int size = array.Length;
			BeforeInitialize(persister, size);
			for (int i = 0; i < size; i += 2)
			{
				identifiers[i / 2] = persister.IdentifierType.Assemble(array[i], Session, owner);
				values.Add(persister.ElementType.Assemble(array[i + 1], Session, owner));
			}
		}
		/// <summary> 
		/// Removes a persistent collection from its loaded owner. 
		/// </summary>
		/// <param name="collection">The collection to to remove; must be non-null </param>
		/// <param name="persister"> The collection's persister </param>
		/// <param name="id">The collection key </param>
		/// <param name="emptySnapshot">Indicates if the snapshot is empty </param>
		/// <param name="session">The session </param>
		/// <remarks>Use this constructor when the collection is non-null.</remarks>
		public CollectionRemoveAction(IPersistentCollection collection, ICollectionPersister persister, object id,
		                              bool emptySnapshot, ISessionImplementor session)
			: base(persister, collection, id, session)
		{
			if (collection == null)
			{
				throw new AssertionFailure("collection == null");
			}

			this.emptySnapshot = emptySnapshot;
			affectedOwner = session.PersistenceContext.GetLoadedCollectionOwnerOrNull(collection);
		}
Example #28
0
		/// <summary>
		/// Returns a Hashtable where the Key &amp; the Value are both a Copy of the
		/// same object.
		/// <see cref="AbstractPersistentCollection.Snapshot(ICollectionPersister)"/>
		/// </summary>
		/// <param name="persister"></param>
		protected override ICollection Snapshot(ICollectionPersister persister)
		{
			EntityMode entityMode = Session.EntityMode;

			Hashtable clonedMap = new Hashtable(internalSet.Count);
			foreach (object obj in internalSet)
			{
				object copied = persister.ElementType.DeepCopy(obj, entityMode, persister.Factory);
				clonedMap[copied] = copied;
			}
			return clonedMap;
		}
		public override ICollection GetSnapshot(ICollectionPersister persister)
		{
			EntityMode entityMode = Session.EntityMode;

			List<object> clonedList = new List<object>(list.Count);
			foreach (object current in list)
			{
				object deepCopy = persister.ElementType.DeepCopy(current, entityMode, persister.Factory);
				clonedList.Add(deepCopy);
			}
			return clonedList;
		}
		public override object ReadFrom(IDataReader reader, ICollectionPersister role, ICollectionAliases descriptor,
		                                object owner)
		{
			// note that if we load this collection from a cartesian product
			// the multiplicity would be broken ... so use an idbag instead
			object element = role.ReadElement(reader, owner, descriptor.SuffixedElementAliases, Session);
			// NH Different behavior : we don't check for null
			// The NH-750 test show how checking for null we are ignoring the not-found tag and
			// the DB may have some records ignored by NH. This issue may need some more deep consideration.
			//if (element != null)
				bag.Add(element);
			return element;
		}