コード例 #1
0
        /// <summary>
        /// Retrieve the collection that is being loaded as part of processing this result set.
        /// </summary>
        /// <param name="persister">The persister for the collection being requested. </param>
        /// <param name="key">The key of the collection being requested. </param>
        /// <returns> The loading collection (see discussion above). </returns>
        /// <remarks>
        /// Basically, there are two valid return values from this method:<ul>
        /// <li>an instance of {@link PersistentCollection} which indicates to
        /// continue loading the result set row data into that returned collection
        /// instance; this may be either an instance already associated and in the
        /// midst of being loaded, or a newly instantiated instance as a matching
        /// associated collection was not found.</li>
        /// <li><i>null</i> indicates to ignore the corresponding result set row
        /// data relating to the requested collection; this indicates that either
        /// the collection was found to already be associated with the persistence
        /// context in a fully loaded state, or it was found in a loading state
        /// associated with another result set processing context.</li>
        /// </ul>
        /// </remarks>
        public IPersistentCollection GetLoadingCollection(ICollectionPersister persister, object key)
        {
            CollectionKey collectionKey = new CollectionKey(persister, key);

            if (log.IsDebugEnabled())
            {
                log.Debug("starting attempt to find loading collection [{0}]", MessageHelper.InfoString(persister.Role, key));
            }
            LoadingCollectionEntry loadingCollectionEntry = loadContexts.LocateLoadingCollectionEntry(collectionKey);

            if (loadingCollectionEntry == null)
            {
                // look for existing collection as part of the persistence context
                IPersistentCollection collection = loadContexts.PersistenceContext.GetCollection(collectionKey);
                if (collection != null)
                {
                    if (collection.WasInitialized)
                    {
                        log.Debug("collection already initialized; ignoring");
                        return(null);                        // ignore this row of results! Note the early exit
                    }
                    else
                    {
                        // initialize this collection
                        log.Debug("collection not yet initialized; initializing");
                    }
                }
                else
                {
                    object owner            = loadContexts.PersistenceContext.GetCollectionOwner(key, persister);
                    bool   newlySavedEntity = owner != null && loadContexts.PersistenceContext.GetEntry(owner).Status != Status.Loading;
                    if (newlySavedEntity)
                    {
                        // important, to account for newly saved entities in query
                        // todo : some kind of check for new status...
                        log.Debug("owning entity already loaded; ignoring");
                        return(null);
                    }
                    else
                    {
                        // create one
                        if (log.IsDebugEnabled())
                        {
                            // Do not log the resultSet as-is, it is an IEnumerable which may get enumerated by loggers.
                            // (Serilog does that.) See #1667.
                            log.Debug("instantiating new collection [key={0}, rs={1}]", key, resultSet.GetType());
                        }
                        collection = persister.CollectionType.Instantiate(loadContexts.PersistenceContext.Session, persister, key);
                    }
                }
                collection.BeforeInitialize(persister, -1);
                collection.BeginRead();
                localLoadingCollectionKeys.Add(collectionKey);
                loadContexts.RegisterLoadingCollectionXRef(collectionKey, new LoadingCollectionEntry(resultSet, persister, key, collection));
                return(collection);
            }
            else
            {
                if (loadingCollectionEntry.ResultSet == resultSet)
                {
                    log.Debug("found loading collection bound to current result set processing; reading row");
                    return(loadingCollectionEntry.Collection);
                }
                else
                {
                    // ignore this row, the collection is in process of
                    // being loaded somewhere further "up" the stack
                    log.Debug("collection is already being initialized; ignoring row");
                    return(null);
                }
            }
        }