/// <summary> /// Force initialization of all non-lazy collections encountered during /// the current two-phase load (actually, this is a no-op, unless this /// is the "outermost" load) /// </summary> /// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param> public async Task InitializeNonLazyCollectionsAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); if (loadCounter == 0) { log.Debug("initializing non-lazy collections"); //do this work only at the very highest level of the load loadCounter++; //don't let this method be called recursively try { while (nonlazyCollections.Count > 0) { //note that each iteration of the loop may add new elements IPersistentCollection tempObject = nonlazyCollections[nonlazyCollections.Count - 1]; nonlazyCollections.RemoveAt(nonlazyCollections.Count - 1); await(tempObject.ForceInitializationAsync(cancellationToken)).ConfigureAwait(false); } } finally { loadCounter--; ClearNullProperties(); } } }
private static Task PrepareCollectionForUpdateAsync(IPersistentCollection collection, CollectionEntry entry, ISessionFactoryImplementor factory, CancellationToken cancellationToken) { //1. record the collection role that this collection is referenced by //2. decide if the collection needs deleting/creating/updating (but don't actually schedule the action yet) if (entry.IsProcessed) { throw new AssertionFailure("collection was processed twice by flush()"); } if (cancellationToken.IsCancellationRequested) { return(Task.FromCanceled <object>(cancellationToken)); } try { entry.IsProcessed = true; ICollectionPersister loadedPersister = entry.LoadedPersister; ICollectionPersister currentPersister = entry.CurrentPersister; if (loadedPersister != null || currentPersister != null) { // it is or was referenced _somewhere_ bool ownerChanged = loadedPersister != currentPersister || !currentPersister.KeyType.IsEqual(entry.LoadedKey, entry.CurrentKey, factory); if (ownerChanged) { // do a check bool orphanDeleteAndRoleChanged = loadedPersister != null && currentPersister != null && loadedPersister.HasOrphanDelete; if (orphanDeleteAndRoleChanged) { return(Task.FromException <object>(new HibernateException("Don't change the reference to a collection with cascade=\"all-delete-orphan\": " + loadedPersister.Role))); } // do the work if (currentPersister != null) { entry.IsDorecreate = true; // we will need to create new entries } if (loadedPersister != null) { entry.IsDoremove = true; // we will need to remove ye olde entries if (entry.IsDorecreate) { log.Debug("Forcing collection initialization"); return(collection.ForceInitializationAsync(cancellationToken)); // force initialize! } } } else if (collection.IsDirty) { // else if it's elements changed entry.IsDoupdate = true; } } return(Task.CompletedTask); } catch (System.Exception ex) { return(Task.FromException <object>(ex)); } }