From: <fab...@us...> - 2008-08-20 20:07:49
|
Revision: 3721 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3721&view=rev Author: fabiomaulo Date: 2008-08-20 20:07:55 +0000 (Wed, 20 Aug 2008) Log Message: ----------- End porting of new events for collections (need some "more" investigation of tests for ManyToMany) Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Action/CollectionRecreateAction.cs trunk/nhibernate/src/NHibernate/Action/CollectionRemoveAction.cs trunk/nhibernate/src/NHibernate/Action/CollectionUpdateAction.cs trunk/nhibernate/src/NHibernate/Event/Default/ReattachVisitor.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/Events/Collections/ trunk/nhibernate/src/NHibernate.Test/Events/Collections/AbstractCollectionEventFixture.cs trunk/nhibernate/src/NHibernate.Test/Events/Collections/AbstractParentWithCollection.cs trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/ trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/AbstractAssociationCollectionEventFixture.cs trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/ trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/ManyToMany/ trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/ManyToMany/BidirectionalManyToManyBagToSetCollectionEventFixture.cs trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/ManyToMany/BidirectionalManyToManyBagToSetMapping.hbm.xml trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/ManyToMany/BidirectionalManyToManySetToSetCollectionEventFixture.cs trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/ManyToMany/BidirectionalManyToManySetToSetMapping.hbm.xml trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/ManyToMany/ChildWithBidirectionalManyToMany.cs trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/ManyToMany/ParentWithBidirectionalManyToMany.cs trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/OneToMany/ trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/OneToMany/BidirectionalOneToManyBagCollectionEventFixture.cs trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/OneToMany/BidirectionalOneToManyBagMapping.hbm.xml trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/OneToMany/BidirectionalOneToManyBagSubclassCollectionEventFixture.cs trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/OneToMany/BidirectionalOneToManyBagSubclassMapping.hbm.xml trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/OneToMany/BidirectionalOneToManySetCollectionEventFixture.cs trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/OneToMany/BidirectionalOneToManySetMapping.hbm.xml trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/OneToMany/ChildWithManyToOne.cs trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/OneToMany/ParentWithBidirectionalOneToMany.cs trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/OneToMany/ParentWithBidirectionalOneToManySubclass.cs trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Unidirectional/ trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Unidirectional/ManyToMany/ trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Unidirectional/ManyToMany/UnidirectionalManyToManyBagCollectionEventFixture.cs trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Unidirectional/ManyToMany/UnidirectionalManyToManyBagMapping.hbm.xml trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Unidirectional/OneToMany/ trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Unidirectional/OneToMany/UnidirectionalOneToManyBagCollectionEventFixture.cs trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Unidirectional/OneToMany/UnidirectionalOneToManyBagMapping.hbm.xml trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Unidirectional/OneToMany/UnidirectionalOneToManySetCollectionEventFixture.cs trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Unidirectional/OneToMany/UnidirectionalOneToManySetMapping.hbm.xml trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Unidirectional/ParentWithCollectionOfEntities.cs trunk/nhibernate/src/NHibernate.Test/Events/Collections/ChildEntity.cs trunk/nhibernate/src/NHibernate.Test/Events/Collections/ChildValue.cs trunk/nhibernate/src/NHibernate.Test/Events/Collections/CollectionListeners.cs trunk/nhibernate/src/NHibernate.Test/Events/Collections/IChild.cs trunk/nhibernate/src/NHibernate.Test/Events/Collections/IEntity.cs trunk/nhibernate/src/NHibernate.Test/Events/Collections/IParentWithCollection.cs trunk/nhibernate/src/NHibernate.Test/Events/Collections/Values/ trunk/nhibernate/src/NHibernate.Test/Events/Collections/Values/ParentWithCollectionOfValues.cs trunk/nhibernate/src/NHibernate.Test/Events/Collections/Values/ValuesBagCollectionEventFixture.cs trunk/nhibernate/src/NHibernate.Test/Events/Collections/Values/ValuesBagMapping.hbm.xml Modified: trunk/nhibernate/src/NHibernate/Action/CollectionRecreateAction.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Action/CollectionRecreateAction.cs 2008-08-19 13:23:30 UTC (rev 3720) +++ trunk/nhibernate/src/NHibernate/Action/CollectionRecreateAction.cs 2008-08-20 20:07:55 UTC (rev 3721) @@ -1,6 +1,7 @@ using System; using NHibernate.Collection; using NHibernate.Engine; +using NHibernate.Event; using NHibernate.Persister.Collection; namespace NHibernate.Action @@ -16,16 +17,46 @@ { IPersistentCollection collection = Collection; + PreRecreate(); + Persister.Recreate(collection, Key, Session); Session.PersistenceContext.GetCollectionEntry(collection).AfterAction(collection); Evict(); + PostRecreate(); + if (Session.Factory.Statistics.IsStatisticsEnabled) { Session.Factory.StatisticsImplementor.RecreateCollection(Persister.Role); } } + + private void PreRecreate() + { + IPreCollectionRecreateEventListener[] preListeners = Session.Listeners.PreCollectionRecreateEventListeners; + if (preListeners.Length > 0) + { + PreCollectionRecreateEvent preEvent = new PreCollectionRecreateEvent(Persister, Collection, (IEventSource)Session); + for (int i = 0; i < preListeners.Length; i++) + { + preListeners[i].OnPreRecreateCollection(preEvent); + } + } + } + + private void PostRecreate() + { + IPostCollectionRecreateEventListener[] postListeners = Session.Listeners.PostCollectionRecreateEventListeners; + if (postListeners.Length > 0) + { + PostCollectionRecreateEvent postEvent = new PostCollectionRecreateEvent(Persister, Collection, (IEventSource)Session); + for (int i = 0; i < postListeners.Length; i++) + { + postListeners[i].OnPostRecreateCollection(postEvent); + } + } + } } } \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Action/CollectionRemoveAction.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Action/CollectionRemoveAction.cs 2008-08-19 13:23:30 UTC (rev 3720) +++ trunk/nhibernate/src/NHibernate/Action/CollectionRemoveAction.cs 2008-08-20 20:07:55 UTC (rev 3721) @@ -1,26 +1,67 @@ using System; using NHibernate.Collection; using NHibernate.Engine; +using NHibernate.Event; using NHibernate.Persister.Collection; namespace NHibernate.Action { [Serializable] - public sealed class CollectionRemoveAction : CollectionAction + public sealed class CollectionRemoveAction : CollectionAction { private readonly bool emptySnapshot; + private readonly object affectedOwner; - public CollectionRemoveAction(IPersistentCollection collection, ICollectionPersister persister, - object key, bool emptySnapshot, ISessionImplementor session) - : base(persister, collection, key, session) + /// <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); } + /// <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; + } + public override void Execute() { + PreRemove(); + if (!emptySnapshot) + { Persister.Remove(Key, Session); + } IPersistentCollection collection = Collection; if (collection != null) @@ -30,15 +71,45 @@ Evict(); + PostRemove(); + if (Session.Factory.Statistics.IsStatisticsEnabled) { Session.Factory.StatisticsImplementor.RemoveCollection(Persister.Role); } } + private void PreRemove() + { + IPreCollectionRemoveEventListener[] preListeners = Session.Listeners.PreCollectionRemoveEventListeners; + if (preListeners.Length > 0) + { + PreCollectionRemoveEvent preEvent = new PreCollectionRemoveEvent(Persister, Collection, (IEventSource) Session, + affectedOwner); + for (int i = 0; i < preListeners.Length; i++) + { + preListeners[i].OnPreRemoveCollection(preEvent); + } + } + } + + private void PostRemove() + { + IPostCollectionRemoveEventListener[] postListeners = Session.Listeners.PostCollectionRemoveEventListeners; + if (postListeners.Length > 0) + { + PostCollectionRemoveEvent postEvent = new PostCollectionRemoveEvent(Persister, Collection, (IEventSource) Session, + affectedOwner); + for (int i = 0; i < postListeners.Length; i++) + { + postListeners[i].OnPostRemoveCollection(postEvent); + } + } + } + public override int CompareTo(CollectionAction other) { return 0; } } -} +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate/Action/CollectionUpdateAction.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Action/CollectionUpdateAction.cs 2008-08-19 13:23:30 UTC (rev 3720) +++ trunk/nhibernate/src/NHibernate/Action/CollectionUpdateAction.cs 2008-08-20 20:07:55 UTC (rev 3721) @@ -3,6 +3,7 @@ using NHibernate.Cache.Entry; using NHibernate.Collection; using NHibernate.Engine; +using NHibernate.Event; using NHibernate.Impl; using NHibernate.Persister.Collection; @@ -28,6 +29,8 @@ IPersistentCollection collection = Collection; bool affectedByFilters = persister.IsAffectedByEnabledFilters(session); + PreUpdate(); + if (!collection.WasInitialized) { if (!collection.HasQueuedOperations) @@ -67,12 +70,40 @@ Evict(); + PostUpdate(); + if (Session.Factory.Statistics.IsStatisticsEnabled) { Session.Factory.StatisticsImplementor.UpdateCollection(Persister.Role); } } + private void PreUpdate() + { + IPreCollectionUpdateEventListener[] preListeners = Session.Listeners.PreCollectionUpdateEventListeners; + if (preListeners.Length > 0) + { + PreCollectionUpdateEvent preEvent = new PreCollectionUpdateEvent(Persister, Collection, (IEventSource)Session); + for (int i = 0; i < preListeners.Length; i++) + { + preListeners[i].OnPreUpdateCollection(preEvent); + } + } + } + + private void PostUpdate() + { + IPostCollectionUpdateEventListener[] postListeners = Session.Listeners.PostCollectionUpdateEventListeners; + if (postListeners.Length > 0) + { + PostCollectionUpdateEvent postEvent = new PostCollectionUpdateEvent(Persister, Collection, (IEventSource)Session); + for (int i = 0; i < postListeners.Length; i++) + { + postListeners[i].OnPostUpdateCollection(postEvent); + } + } + } + public override void AfterTransactionCompletion(bool success) { // NH Different behavior: to support unlocking collections from the cache.(r3260) Modified: trunk/nhibernate/src/NHibernate/Event/Default/ReattachVisitor.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Event/Default/ReattachVisitor.cs 2008-08-19 13:23:30 UTC (rev 3720) +++ trunk/nhibernate/src/NHibernate/Event/Default/ReattachVisitor.cs 2008-08-20 20:07:55 UTC (rev 3721) @@ -15,7 +15,7 @@ private readonly object owner; private static readonly ILog log = LogManager.GetLogger(typeof(AbstractFlushingEventListener)); - public ReattachVisitor(IEventSource session, object ownerIdentifier, object owner) + protected ReattachVisitor(IEventSource session, object ownerIdentifier, object owner) : base(session) { this.ownerIdentifier = ownerIdentifier; @@ -60,7 +60,7 @@ log.Debug("collection dereferenced while transient " + MessageHelper.InfoString(role, ownerIdentifier, source.Factory)); } - source.ActionQueue.AddAction(new CollectionRemoveAction(null, role, collectionKey, false, source)); + source.ActionQueue.AddAction(new CollectionRemoveAction(owner, role, collectionKey, false, source)); } /// <summary> Added: trunk/nhibernate/src/NHibernate.Test/Events/Collections/AbstractCollectionEventFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Events/Collections/AbstractCollectionEventFixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Events/Collections/AbstractCollectionEventFixture.cs 2008-08-20 20:07:55 UTC (rev 3721) @@ -0,0 +1,907 @@ +using System.Collections; +using System.Collections.Generic; +using NHibernate.Collection; +using NHibernate.Event; +using NHibernate.Test.Events.Collections.Association.Bidirectional.ManyToMany; +using NUnit.Framework; +using NUnit.Framework.SyntaxHelpers; + +namespace NHibernate.Test.Events.Collections +{ + public abstract class AbstractCollectionEventFixture : TestCase + { + protected override string MappingsAssembly + { + get { return "NHibernate.Test"; } + } + + public abstract IParentWithCollection CreateParent(string name); + + public abstract ICollection<IChild> CreateCollection(); + + protected override void OnTearDown() + { + IParentWithCollection dummyParent = CreateParent("dummyParent"); + dummyParent.NewChildren(CreateCollection()); + IChild dummyChild = dummyParent.AddChild("dummyChild"); + + using (ISession s = OpenSession()) + { + using (ITransaction tx = s.BeginTransaction()) + { + IList children = s.CreateCriteria(dummyChild.GetType()).List(); + IList parents = s.CreateCriteria(dummyParent.GetType()).List(); + foreach (IParentWithCollection parent in parents) + { + parent.ClearChildren(); + s.Delete(parent); + } + foreach (IChild child in children) + { + s.Delete(child); + } + + tx.Commit(); + } + } + base.OnTearDown(); + } + + [Test] + public void SaveParentEmptyChildren() + { + CollectionListeners listeners = new CollectionListeners(sessions); + IParentWithCollection parent = CreateParentWithNoChildren("parent"); + Assert.That(parent.Children.Count, Is.EqualTo(0)); + int index = 0; + CheckResult(listeners, listeners.PreCollectionRecreate, parent, index++); + CheckResult(listeners, listeners.PostCollectionRecreate, parent, index++); + CheckNumberOfResults(listeners, index); + listeners.Clear(); + using (ISession s = OpenSession()) + { + using (ITransaction tx = s.BeginTransaction()) + { + parent = (IParentWithCollection) s.Get(parent.GetType(), parent.Id); + tx.Commit(); + } + } + Assert.That(parent.Children, Is.Not.Null); + CheckNumberOfResults(listeners, 0); + } + + [Test] + public virtual void SaveParentOneChild() + { + CollectionListeners listeners = new CollectionListeners(sessions); + IParentWithCollection parent = CreateParentWithOneChild("parent", "child"); + int index = 0; + CheckResult(listeners, listeners.PreCollectionRecreate, parent, index++); + CheckResult(listeners, listeners.PostCollectionRecreate, parent, index++); + ChildWithBidirectionalManyToMany child = GetFirstChild(parent.Children) as ChildWithBidirectionalManyToMany; + if (child != null) + { + CheckResult(listeners, listeners.PreCollectionRecreate, child, index++); + CheckResult(listeners, listeners.PostCollectionRecreate, child, index++); + } + + CheckNumberOfResults(listeners, index); + } + + [Test] + public void UpdateParentNullToOneChild() + { + CollectionListeners listeners = new CollectionListeners(sessions); + IParentWithCollection parent = CreateParentWithNullChildren("parent"); + listeners.Clear(); + Assert.That(parent.Children, Is.Null); + ISession s = OpenSession(); + ITransaction tx = s.BeginTransaction(); + parent = (IParentWithCollection) s.Get(parent.GetType(), parent.Id); + Assert.That(parent.Children, Is.Not.Null); + ChildWithBidirectionalManyToMany newChild = parent.AddChild("new") as ChildWithBidirectionalManyToMany; + tx.Commit(); + s.Close(); + int index = 0; + if (((IPersistentCollection) parent.Children).WasInitialized) + { + CheckResult(listeners, listeners.InitializeCollection, parent, index++); + } + CheckResult(listeners, listeners.PreCollectionUpdate, parent, index++); + CheckResult(listeners, listeners.PostCollectionUpdate, parent, index++); + if (newChild != null) + { + CheckResult(listeners, listeners.PreCollectionRecreate, newChild, index++); + CheckResult(listeners, listeners.PostCollectionRecreate, newChild, index++); + } + + CheckNumberOfResults(listeners, index); + } + + [Test] + public void UpdateParentNoneToOneChild() + { + CollectionListeners listeners = new CollectionListeners(sessions); + IParentWithCollection parent = CreateParentWithNoChildren("parent"); + listeners.Clear(); + Assert.That(parent.Children.Count, Is.EqualTo(0)); + ISession s = OpenSession(); + ITransaction tx = s.BeginTransaction(); + parent = (IParentWithCollection) s.Get(parent.GetType(), parent.Id); + ChildWithBidirectionalManyToMany newChild = parent.AddChild("new") as ChildWithBidirectionalManyToMany; + tx.Commit(); + s.Close(); + int index = 0; + if (((IPersistentCollection) parent.Children).WasInitialized) + { + CheckResult(listeners, listeners.InitializeCollection, parent, index++); + } + CheckResult(listeners, listeners.PreCollectionUpdate, parent, index++); + CheckResult(listeners, listeners.PostCollectionUpdate, parent, index++); + if (newChild != null) + { + CheckResult(listeners, listeners.PreCollectionRecreate, newChild, index++); + CheckResult(listeners, listeners.PostCollectionRecreate, newChild, index++); + } + + CheckNumberOfResults(listeners, index); + } + + [Test] + public void UpdateParentOneToTwoChildren() + { + CollectionListeners listeners = new CollectionListeners(sessions); + IParentWithCollection parent = CreateParentWithOneChild("parent", "child"); + Assert.That(parent.Children.Count, Is.EqualTo(1)); + listeners.Clear(); + ISession s = OpenSession(); + ITransaction tx = s.BeginTransaction(); + parent = (IParentWithCollection) s.Get(parent.GetType(), parent.Id); + ChildWithBidirectionalManyToMany newChild = parent.AddChild("new2") as ChildWithBidirectionalManyToMany; + tx.Commit(); + s.Close(); + int index = 0; + if (((IPersistentCollection) parent.Children).WasInitialized) + { + CheckResult(listeners, listeners.InitializeCollection, parent, index++); + } + CheckResult(listeners, listeners.PreCollectionUpdate, parent, index++); + CheckResult(listeners, listeners.PostCollectionUpdate, parent, index++); + if (newChild != null) + { + CheckResult(listeners, listeners.PreCollectionRecreate, newChild, index++); + CheckResult(listeners, listeners.PostCollectionRecreate, newChild, index++); + } + + CheckNumberOfResults(listeners, index); + } + + [Test] + public void UpdateParentOneToTwoSameChildren() + { + CollectionListeners listeners = new CollectionListeners(sessions); + IParentWithCollection parent = CreateParentWithOneChild("parent", "child"); + IChild child = GetFirstChild(parent.Children); + Assert.That(parent.Children.Count, Is.EqualTo(1)); + listeners.Clear(); + ISession s = OpenSession(); + ITransaction tx = s.BeginTransaction(); + parent = (IParentWithCollection) s.Get(parent.GetType(), parent.Id); + IEntity e = child as IEntity; + if (e != null) + { + child = (IChild) s.Get(child.GetType(), e.Id); + } + parent.AddChild(child); + tx.Commit(); + s.Close(); + int index = 0; + if (((IPersistentCollection) parent.Children).WasInitialized) + { + CheckResult(listeners, listeners.InitializeCollection, parent, index++); + } + ChildWithBidirectionalManyToMany childWithManyToMany = child as ChildWithBidirectionalManyToMany; + if (childWithManyToMany != null) + { + if (((IPersistentCollection) childWithManyToMany.Parents).WasInitialized) + { + CheckResult(listeners, listeners.InitializeCollection, childWithManyToMany, index++); + } + } + + if (!(parent.Children is PersistentSet)) + { + CheckResult(listeners, listeners.PreCollectionUpdate, parent, index++); + CheckResult(listeners, listeners.PostCollectionUpdate, parent, index++); + } + if (childWithManyToMany != null && !(childWithManyToMany.Parents is PersistentSet)) + { + CheckResult(listeners, listeners.PreCollectionUpdate, childWithManyToMany, index++); + CheckResult(listeners, listeners.PostCollectionUpdate, childWithManyToMany, index++); + } + + CheckNumberOfResults(listeners, index); + } + + [Test] + public void UpdateParentNullToOneChildDiffCollection() + { + CollectionListeners listeners = new CollectionListeners(sessions); + IParentWithCollection parent = CreateParentWithNullChildren("parent"); + listeners.Clear(); + Assert.That(parent.Children, Is.Null); + ISession s = OpenSession(); + ITransaction tx = s.BeginTransaction(); + parent = (IParentWithCollection) s.Get(parent.GetType(), parent.Id); + ICollection<IChild> collectionOrig = parent.Children; + parent.NewChildren(CreateCollection()); + ChildWithBidirectionalManyToMany newChild = parent.AddChild("new") as ChildWithBidirectionalManyToMany; + tx.Commit(); + s.Close(); + int index = 0; + if (((IPersistentCollection) collectionOrig).WasInitialized) + { + CheckResult(listeners, listeners.InitializeCollection, parent, collectionOrig, index++); + } + CheckResult(listeners, listeners.PreCollectionRemove, parent, collectionOrig, index++); + CheckResult(listeners, listeners.PostCollectionRemove, parent, collectionOrig, index++); + if (newChild != null) + { + CheckResult(listeners, listeners.PreCollectionRecreate, newChild, index++); + CheckResult(listeners, listeners.PostCollectionRecreate, newChild, index++); + } + CheckResult(listeners, listeners.PreCollectionRecreate, parent, index++); + CheckResult(listeners, listeners.PostCollectionRecreate, parent, index++); + CheckNumberOfResults(listeners, index); + } + + [Test] + public void UpdateParentNoneToOneChildDiffCollection() + { + CollectionListeners listeners = new CollectionListeners(sessions); + IParentWithCollection parent = CreateParentWithNoChildren("parent"); + listeners.Clear(); + Assert.That(parent.Children.Count, Is.EqualTo(0)); + ISession s = OpenSession(); + ITransaction tx = s.BeginTransaction(); + parent = (IParentWithCollection) s.Get(parent.GetType(), parent.Id); + ICollection<IChild> oldCollection = parent.Children; + parent.NewChildren(CreateCollection()); + ChildWithBidirectionalManyToMany newChild = parent.AddChild("new") as ChildWithBidirectionalManyToMany; + tx.Commit(); + s.Close(); + int index = 0; + if (((IPersistentCollection) oldCollection).WasInitialized) + { + CheckResult(listeners, listeners.InitializeCollection, parent, oldCollection, index++); + } + CheckResult(listeners, listeners.PreCollectionRemove, parent, oldCollection, index++); + CheckResult(listeners, listeners.PostCollectionRemove, parent, oldCollection, index++); + if (newChild != null) + { + CheckResult(listeners, listeners.PreCollectionRecreate, newChild, index++); + CheckResult(listeners, listeners.PostCollectionRecreate, newChild, index++); + } + + CheckResult(listeners, listeners.PreCollectionRecreate, parent, index++); + CheckResult(listeners, listeners.PostCollectionRecreate, parent, index++); + CheckNumberOfResults(listeners, index); + } + + [Test] + public void UpdateParentOneChildDiffCollectionSameChild() + { + CollectionListeners listeners = new CollectionListeners(sessions); + IParentWithCollection parent = CreateParentWithOneChild("parent", "child"); + IChild child = GetFirstChild(parent.Children); + listeners.Clear(); + Assert.That(parent.Children.Count, Is.EqualTo(1)); + ISession s = OpenSession(); + ITransaction tx = s.BeginTransaction(); + parent = (IParentWithCollection) s.Get(parent.GetType(), parent.Id); + IEntity e = child as IEntity; + if (e != null) + { + child = (IChild) s.Get(child.GetType(), e.Id); + } + ICollection<IChild> oldCollection = parent.Children; + parent.NewChildren(CreateCollection()); + parent.AddChild(child); + tx.Commit(); + s.Close(); + int index = 0; + if (((IPersistentCollection) oldCollection).WasInitialized) + { + CheckResult(listeners, listeners.InitializeCollection, parent, oldCollection, index++); + } + ChildWithBidirectionalManyToMany childWithManyToMany = child as ChildWithBidirectionalManyToMany; + if (childWithManyToMany != null) + { + if (((IPersistentCollection) childWithManyToMany.Parents).WasInitialized) + { + CheckResult(listeners, listeners.InitializeCollection, childWithManyToMany, index++); + } + } + + CheckResult(listeners, listeners.PreCollectionRemove, parent, oldCollection, index++); + CheckResult(listeners, listeners.PostCollectionRemove, parent, oldCollection, index++); + if (childWithManyToMany != null) + { + // hmmm, the same parent was removed and re-added to the child's collection; + // should this be considered an update? + CheckResult(listeners, listeners.PreCollectionUpdate, childWithManyToMany, index++); + CheckResult(listeners, listeners.PostCollectionUpdate, childWithManyToMany, index++); + } + CheckResult(listeners, listeners.PreCollectionRecreate, parent, index++); + CheckResult(listeners, listeners.PostCollectionRecreate, parent, index++); + CheckNumberOfResults(listeners, index); + } + + [Test] + public void UpdateParentOneChildDiffCollectionDiffChild() + { + CollectionListeners listeners = new CollectionListeners(sessions); + IParentWithCollection parent = CreateParentWithOneChild("parent", "child"); + IChild oldChild = GetFirstChild(parent.Children); + listeners.Clear(); + Assert.That(parent.Children.Count, Is.EqualTo(1)); + ISession s = OpenSession(); + ITransaction tx = s.BeginTransaction(); + parent = (IParentWithCollection) s.Get(parent.GetType(), parent.Id); + IEntity e = oldChild as IEntity; + ChildWithBidirectionalManyToMany oldChildWithManyToMany = null; + if (e != null) + { + oldChildWithManyToMany = s.Get(oldChild.GetType(), e.Id) as ChildWithBidirectionalManyToMany; + } + ICollection<IChild> oldCollection = parent.Children; + parent.NewChildren(CreateCollection()); + IChild newChild = parent.AddChild("new1"); + tx.Commit(); + s.Close(); + int index = 0; + if (((IPersistentCollection) oldCollection).WasInitialized) + { + CheckResult(listeners, listeners.InitializeCollection, parent, oldCollection, index++); + } + if (oldChildWithManyToMany != null) + { + if (((IPersistentCollection) oldChildWithManyToMany.Parents).WasInitialized) + { + CheckResult(listeners, listeners.InitializeCollection, oldChildWithManyToMany, index++); + } + } + CheckResult(listeners, listeners.PreCollectionRemove, parent, oldCollection, index++); + CheckResult(listeners, listeners.PostCollectionRemove, parent, oldCollection, index++); + if (oldChildWithManyToMany != null) + { + CheckResult(listeners, listeners.PreCollectionUpdate, oldChildWithManyToMany, index++); + CheckResult(listeners, listeners.PostCollectionUpdate, oldChildWithManyToMany, index++); + CheckResult(listeners, listeners.PreCollectionRecreate, (ChildWithBidirectionalManyToMany) newChild, index++); + CheckResult(listeners, listeners.PostCollectionRecreate, (ChildWithBidirectionalManyToMany) newChild, index++); + } + CheckResult(listeners, listeners.PreCollectionRecreate, parent, index++); + CheckResult(listeners, listeners.PostCollectionRecreate, parent, index++); + CheckNumberOfResults(listeners, index); + } + + [Test] + public void UpdateParentOneChildToNoneByRemove() + { + CollectionListeners listeners = new CollectionListeners(sessions); + IParentWithCollection parent = CreateParentWithOneChild("parent", "child"); + Assert.That(parent.Children.Count, Is.EqualTo(1)); + IChild child = GetFirstChild(parent.Children); + listeners.Clear(); + ISession s = OpenSession(); + ITransaction tx = s.BeginTransaction(); + parent = (IParentWithCollection) s.Get(parent.GetType(), parent.Id); + IEntity e = child as IEntity; + + if (e != null) + { + child = (IChild) s.Get(child.GetType(), e.Id); + } + parent.RemoveChild(child); + tx.Commit(); + s.Close(); + int index = 0; + if (((IPersistentCollection) parent.Children).WasInitialized) + { + CheckResult(listeners, listeners.InitializeCollection, parent, index++); + } + ChildWithBidirectionalManyToMany childWithManyToMany = child as ChildWithBidirectionalManyToMany; + if (childWithManyToMany != null) + { + if (((IPersistentCollection) childWithManyToMany.Parents).WasInitialized) + { + CheckResult(listeners, listeners.InitializeCollection, childWithManyToMany, index++); + } + } + CheckResult(listeners, listeners.PreCollectionUpdate, parent, index++); + CheckResult(listeners, listeners.PostCollectionUpdate, parent, index++); + if (childWithManyToMany != null) + { + CheckResult(listeners, listeners.PreCollectionUpdate, childWithManyToMany, index++); + CheckResult(listeners, listeners.PostCollectionUpdate, childWithManyToMany, index++); + } + CheckNumberOfResults(listeners, index); + } + + [Test] + public void UpdateParentOneChildToNoneByClear() + { + CollectionListeners listeners = new CollectionListeners(sessions); + IParentWithCollection parent = CreateParentWithOneChild("parent", "child"); + Assert.That(parent.Children.Count, Is.EqualTo(1)); + IChild child = GetFirstChild(parent.Children); + listeners.Clear(); + ISession s = OpenSession(); + ITransaction tx = s.BeginTransaction(); + parent = (IParentWithCollection) s.Get(parent.GetType(), parent.Id); + IEntity e = child as IEntity; + if (e != null) + { + child = (IChild) s.Get(child.GetType(), e.Id); + } + parent.ClearChildren(); + tx.Commit(); + s.Close(); + int index = 0; + if (((IPersistentCollection) parent.Children).WasInitialized) + { + CheckResult(listeners, listeners.InitializeCollection, parent, index++); + } + ChildWithBidirectionalManyToMany childWithManyToMany = child as ChildWithBidirectionalManyToMany; + if (childWithManyToMany != null) + { + if (((IPersistentCollection) childWithManyToMany.Parents).WasInitialized) + { + CheckResult(listeners, listeners.InitializeCollection, childWithManyToMany, index++); + } + } + CheckResult(listeners, listeners.PreCollectionUpdate, parent, index++); + CheckResult(listeners, listeners.PostCollectionUpdate, parent, index++); + if (childWithManyToMany != null) + { + CheckResult(listeners, listeners.PreCollectionUpdate, childWithManyToMany, index++); + CheckResult(listeners, listeners.PostCollectionUpdate, childWithManyToMany, index++); + } + CheckNumberOfResults(listeners, index); + } + + [Test] + public void UpdateParentTwoChildrenToOne() + { + CollectionListeners listeners = new CollectionListeners(sessions); + IParentWithCollection parent = CreateParentWithOneChild("parent", "child"); + Assert.That(parent.Children.Count, Is.EqualTo(1)); + IChild oldChild = GetFirstChild(parent.Children); + listeners.Clear(); + ISession s = OpenSession(); + ITransaction tx = s.BeginTransaction(); + parent = (IParentWithCollection) s.Get(parent.GetType(), parent.Id); + parent.AddChild("new"); + tx.Commit(); + s.Close(); + listeners.Clear(); + s = OpenSession(); + tx = s.BeginTransaction(); + parent = (IParentWithCollection) s.Get(parent.GetType(), parent.Id); + IEntity e = oldChild as IEntity; + if (e != null) + { + oldChild = (IChild) s.Get(oldChild.GetType(), e.Id); + } + + parent.RemoveChild(oldChild); + tx.Commit(); + s.Close(); + int index = 0; + if (((IPersistentCollection) parent.Children).WasInitialized) + { + CheckResult(listeners, listeners.InitializeCollection, parent, index++); + } + ChildWithBidirectionalManyToMany oldChildWithManyToMany = oldChild as ChildWithBidirectionalManyToMany; + if (oldChildWithManyToMany != null) + { + if (((IPersistentCollection) oldChildWithManyToMany.Parents).WasInitialized) + { + CheckResult(listeners, listeners.InitializeCollection, oldChildWithManyToMany, index++); + } + } + + CheckResult(listeners, listeners.PreCollectionUpdate, parent, index++); + CheckResult(listeners, listeners.PostCollectionUpdate, parent, index++); + if (oldChildWithManyToMany != null) + { + CheckResult(listeners, listeners.PreCollectionUpdate, oldChildWithManyToMany, index++); + CheckResult(listeners, listeners.PostCollectionUpdate, oldChildWithManyToMany, index++); + } + CheckNumberOfResults(listeners, index); + } + + [Test] + public void DeleteParentWithNullChildren() + { + CollectionListeners listeners = new CollectionListeners(sessions); + IParentWithCollection parent = CreateParentWithNullChildren("parent"); + listeners.Clear(); + ISession s = OpenSession(); + ITransaction tx = s.BeginTransaction(); + parent = (IParentWithCollection) s.Get(parent.GetType(), parent.Id); + s.Delete(parent); + tx.Commit(); + s.Close(); + int index = 0; + CheckResult(listeners, listeners.InitializeCollection, parent, index++); + CheckResult(listeners, listeners.PreCollectionRemove, parent, index++); + CheckResult(listeners, listeners.PostCollectionRemove, parent, index++); + CheckNumberOfResults(listeners, index); + } + + [Test] + public void DeleteParentWithNoChildren() + { + CollectionListeners listeners = new CollectionListeners(sessions); + IParentWithCollection parent = CreateParentWithNoChildren("parent"); + listeners.Clear(); + ISession s = OpenSession(); + ITransaction tx = s.BeginTransaction(); + parent = (IParentWithCollection) s.Get(parent.GetType(), parent.Id); + s.Delete(parent); + tx.Commit(); + s.Close(); + + int index = 0; + CheckResult(listeners, listeners.InitializeCollection, parent, index++); + CheckResult(listeners, listeners.PreCollectionRemove, parent, index++); + CheckResult(listeners, listeners.PostCollectionRemove, parent, index++); + CheckNumberOfResults(listeners, index); + } + + [Test] + public void DeleteParentAndChild() + { + CollectionListeners listeners = new CollectionListeners(sessions); + IParentWithCollection parent = CreateParentWithOneChild("parent", "child"); + IChild child = GetFirstChild(parent.Children); + listeners.Clear(); + ISession s = OpenSession(); + ITransaction tx = s.BeginTransaction(); + parent = (IParentWithCollection) s.Get(parent.GetType(), parent.Id); + IEntity e = child as IEntity; + if (e != null) + { + child = (IChild) s.Get(child.GetType(), e.Id); + } + parent.RemoveChild(child); + if (e != null) + { + s.Delete(child); + } + s.Delete(parent); + tx.Commit(); + s.Close(); + int index = 0; + CheckResult(listeners, listeners.InitializeCollection, parent, index++); + ChildWithBidirectionalManyToMany childWithManyToMany = child as ChildWithBidirectionalManyToMany; + if (childWithManyToMany != null) + { + CheckResult(listeners, listeners.InitializeCollection, childWithManyToMany, index++); + } + CheckResult(listeners, listeners.PreCollectionRemove, parent, index++); + CheckResult(listeners, listeners.PostCollectionRemove, parent, index++); + if (childWithManyToMany != null) + { + CheckResult(listeners, listeners.PreCollectionRemove, childWithManyToMany, index++); + CheckResult(listeners, listeners.PostCollectionRemove, childWithManyToMany, index++); + } + CheckNumberOfResults(listeners, index); + } + + [Test] + public void MoveChildToDifferentParent() + { + CollectionListeners listeners = new CollectionListeners(sessions); + IParentWithCollection parent = CreateParentWithOneChild("parent", "child"); + IParentWithCollection otherParent = CreateParentWithOneChild("otherParent", "otherChild"); + IChild child = GetFirstChild(parent.Children); + listeners.Clear(); + ISession s = OpenSession(); + ITransaction tx = s.BeginTransaction(); + parent = (IParentWithCollection) s.Get(parent.GetType(), parent.Id); + otherParent = (IParentWithCollection) s.Get(otherParent.GetType(), otherParent.Id); + IEntity e = child as IEntity; + if (e != null) + { + child = (IChild) s.Get(child.GetType(), e.Id); + } + parent.RemoveChild(child); + otherParent.AddChild(child); + tx.Commit(); + s.Close(); + int index = 0; + if (((IPersistentCollection) parent.Children).WasInitialized) + { + CheckResult(listeners, listeners.InitializeCollection, parent, index++); + } + ChildWithBidirectionalManyToMany childWithManyToMany = child as ChildWithBidirectionalManyToMany; + if (childWithManyToMany != null) + { + CheckResult(listeners, listeners.InitializeCollection, childWithManyToMany, index++); + } + if (((IPersistentCollection) otherParent.Children).WasInitialized) + { + CheckResult(listeners, listeners.InitializeCollection, otherParent, index++); + } + CheckResult(listeners, listeners.PreCollectionUpdate, parent, index++); + CheckResult(listeners, listeners.PostCollectionUpdate, parent, index++); + CheckResult(listeners, listeners.PreCollectionUpdate, otherParent, index++); + CheckResult(listeners, listeners.PostCollectionUpdate, otherParent, index++); + if (childWithManyToMany != null) + { + CheckResult(listeners, listeners.PreCollectionUpdate, childWithManyToMany, index++); + CheckResult(listeners, listeners.PostCollectionUpdate, childWithManyToMany, index++); + } + CheckNumberOfResults(listeners, index); + } + + [Test] + public void MoveAllChildrenToDifferentParent() + { + CollectionListeners listeners = new CollectionListeners(sessions); + IParentWithCollection parent = CreateParentWithOneChild("parent", "child"); + IParentWithCollection otherParent = CreateParentWithOneChild("otherParent", "otherChild"); + IChild child = GetFirstChild(parent.Children); + listeners.Clear(); + ISession s = OpenSession(); + ITransaction tx = s.BeginTransaction(); + parent = (IParentWithCollection) s.Get(parent.GetType(), parent.Id); + otherParent = (IParentWithCollection) s.Get(otherParent.GetType(), otherParent.Id); + IEntity e = child as IEntity; + if (e != null) + { + child = (IChild) s.Get(child.GetType(), e.Id); + } + otherParent.AddAllChildren(parent.Children); + parent.ClearChildren(); + tx.Commit(); + s.Close(); + int index = 0; + if (((IPersistentCollection) parent.Children).WasInitialized) + { + CheckResult(listeners, listeners.InitializeCollection, parent, index++); + } + if (((IPersistentCollection) otherParent.Children).WasInitialized) + { + CheckResult(listeners, listeners.InitializeCollection, otherParent, index++); + } + ChildWithBidirectionalManyToMany childWithManyToMany = child as ChildWithBidirectionalManyToMany; + if (childWithManyToMany != null) + { + CheckResult(listeners, listeners.InitializeCollection, childWithManyToMany, index++); + } + CheckResult(listeners, listeners.PreCollectionUpdate, parent, index++); + CheckResult(listeners, listeners.PostCollectionUpdate, parent, index++); + CheckResult(listeners, listeners.PreCollectionUpdate, otherParent, index++); + CheckResult(listeners, listeners.PostCollectionUpdate, otherParent, index++); + if (childWithManyToMany != null) + { + CheckResult(listeners, listeners.PreCollectionUpdate, childWithManyToMany, index++); + CheckResult(listeners, listeners.PostCollectionUpdate, childWithManyToMany, index++); + } + CheckNumberOfResults(listeners, index); + } + + [Test] + public void MoveCollectionToDifferentParent() + { + CollectionListeners listeners = new CollectionListeners(sessions); + IParentWithCollection parent = CreateParentWithOneChild("parent", "child"); + IParentWithCollection otherParent = CreateParentWithOneChild("otherParent", "otherChild"); + listeners.Clear(); + ISession s = OpenSession(); + ITransaction tx = s.BeginTransaction(); + parent = (IParentWithCollection) s.Get(parent.GetType(), parent.Id); + otherParent = (IParentWithCollection) s.Get(otherParent.GetType(), otherParent.Id); + ICollection<IChild> otherCollectionOrig = otherParent.Children; + otherParent.NewChildren(parent.Children); + parent.NewChildren(null); + tx.Commit(); + s.Close(); + int index = 0; + ChildWithBidirectionalManyToMany otherChildOrig = null; + if (((IPersistentCollection) otherCollectionOrig).WasInitialized) + { + CheckResult(listeners, listeners.InitializeCollection, otherParent, otherCollectionOrig, index++); + otherChildOrig = GetFirstChild(otherCollectionOrig) as ChildWithBidirectionalManyToMany; + if (otherChildOrig != null) + { + CheckResult(listeners, listeners.InitializeCollection, otherChildOrig, index++); + } + } + CheckResult(listeners, listeners.InitializeCollection, parent, otherParent.Children, index++); + ChildWithBidirectionalManyToMany otherChild = GetFirstChild(otherParent.Children) as ChildWithBidirectionalManyToMany; + if (otherChild != null) + { + CheckResult(listeners, listeners.InitializeCollection, otherChild, index++); + } + CheckResult(listeners, listeners.PreCollectionRemove, parent, otherParent.Children, index++); + CheckResult(listeners, listeners.PostCollectionRemove, parent, otherParent.Children, index++); + CheckResult(listeners, listeners.PreCollectionRemove, otherParent, otherCollectionOrig, index++); + CheckResult(listeners, listeners.PostCollectionRemove, otherParent, otherCollectionOrig, index++); + if (otherChild != null) + { + CheckResult(listeners, listeners.PreCollectionUpdate, otherChildOrig, index++); + CheckResult(listeners, listeners.PostCollectionUpdate, otherChildOrig, index++); + CheckResult(listeners, listeners.PreCollectionUpdate, otherChild, index++); + CheckResult(listeners, listeners.PostCollectionUpdate, otherChild, index++); + } + CheckResult(listeners, listeners.PreCollectionRecreate, otherParent, index++); + CheckResult(listeners, listeners.PostCollectionRecreate, otherParent, index++); + // there should also be pre- and post-recreate collection events for parent, but thats broken now; + // this is covered in BrokenCollectionEventTest + CheckNumberOfResults(listeners, index); + } + + [Test] + public void MoveCollectionToDifferentParentFlushMoveToDifferentParent() + { + CollectionListeners listeners = new CollectionListeners(sessions); + IParentWithCollection parent = CreateParentWithOneChild("parent", "child"); + IParentWithCollection otherParent = CreateParentWithOneChild("otherParent", "otherChild"); + IParentWithCollection otherOtherParent = CreateParentWithNoChildren("otherParent"); + listeners.Clear(); + ISession s = OpenSession(); + ITransaction tx = s.BeginTransaction(); + parent = (IParentWithCollection) s.Get(parent.GetType(), parent.Id); + otherParent = (IParentWithCollection) s.Get(otherParent.GetType(), otherParent.Id); + otherOtherParent = (IParentWithCollection) s.Get(otherOtherParent.GetType(), otherOtherParent.Id); + ICollection<IChild> otherCollectionOrig = otherParent.Children; + ICollection<IChild> otherOtherCollectionOrig = otherOtherParent.Children; + otherParent.NewChildren(parent.Children); + parent.NewChildren(null); + s.Flush(); + otherOtherParent.NewChildren(otherParent.Children); + otherParent.NewChildren(null); + tx.Commit(); + s.Close(); + int index = 0; + ChildWithBidirectionalManyToMany otherChildOrig = null; + if (((IPersistentCollection) otherCollectionOrig).WasInitialized) + { + CheckResult(listeners, listeners.InitializeCollection, otherParent, otherCollectionOrig, index++); + otherChildOrig = GetFirstChild(otherCollectionOrig) as ChildWithBidirectionalManyToMany; + if (otherChildOrig != null) + { + CheckResult(listeners, listeners.InitializeCollection, otherChildOrig, index++); + } + } + CheckResult(listeners, listeners.InitializeCollection, parent, otherOtherParent.Children, index++); + ChildWithBidirectionalManyToMany otherOtherChild = + GetFirstChild(otherOtherParent.Children) as ChildWithBidirectionalManyToMany; + if (otherOtherChild != null) + { + CheckResult(listeners, listeners.InitializeCollection, otherOtherChild, index++); + } + CheckResult(listeners, listeners.PreCollectionRemove, parent, otherOtherParent.Children, index++); + CheckResult(listeners, listeners.PostCollectionRemove, parent, otherOtherParent.Children, index++); + CheckResult(listeners, listeners.PreCollectionRemove, otherParent, otherCollectionOrig, index++); + CheckResult(listeners, listeners.PostCollectionRemove, otherParent, otherCollectionOrig, index++); + if (otherOtherChild != null) + { + CheckResult(listeners, listeners.PreCollectionUpdate, otherChildOrig, index++); + CheckResult(listeners, listeners.PostCollectionUpdate, otherChildOrig, index++); + CheckResult(listeners, listeners.PreCollectionUpdate, otherOtherChild, index++); + CheckResult(listeners, listeners.PostCollectionUpdate, otherOtherChild, index++); + } + CheckResult(listeners, listeners.PreCollectionRecreate, otherParent, otherOtherParent.Children, index++); + CheckResult(listeners, listeners.PostCollectionRecreate, otherParent, otherOtherParent.Children, index++); + if (((IPersistentCollection) otherOtherCollectionOrig).WasInitialized) + { + CheckResult(listeners, listeners.InitializeCollection, otherOtherParent, otherOtherCollectionOrig, index++); + } + CheckResult(listeners, listeners.PreCollectionRemove, otherParent, otherOtherParent.Children, index++); + CheckResult(listeners, listeners.PostCollectionRemove, otherParent, otherOtherParent.Children, index++); + CheckResult(listeners, listeners.PreCollectionRemove, otherOtherParent, otherOtherCollectionOrig, index++); + CheckResult(listeners, listeners.PostCollectionRemove, otherOtherParent, otherOtherCollectionOrig, index++); + if (otherOtherChild != null) + { + CheckResult(listeners, listeners.PreCollectionUpdate, otherOtherChild, index++); + CheckResult(listeners, listeners.PostCollectionUpdate, otherOtherChild, index++); + } + + CheckResult(listeners, listeners.PreCollectionRecreate, otherOtherParent, index++); + CheckResult(listeners, listeners.PostCollectionRecreate, otherOtherParent, index++); + // there should also be pre- and post-recreate collection events for parent, and otherParent + // but thats broken now; this is covered in BrokenCollectionEventTest + CheckNumberOfResults(listeners, index); + } + + protected IChild GetFirstChild(ICollection<IChild> children) + { + IChild result = null; + IEnumerator<IChild> en = children.GetEnumerator(); + if (en.MoveNext()) + { + result = en.Current; + } + return result; + } + + protected IParentWithCollection CreateParentWithNullChildren(string parentName) + { + using (ISession s = OpenSession()) + { + using (ITransaction tx = s.BeginTransaction()) + { + IParentWithCollection parent = CreateParent(parentName); + s.Save(parent); + tx.Commit(); + return parent; + } + } + } + + protected IParentWithCollection CreateParentWithNoChildren(string parentName) + { + using (ISession s = OpenSession()) + { + using (ITransaction tx = s.BeginTransaction()) + { + IParentWithCollection parent = CreateParent(parentName); + parent.NewChildren(CreateCollection()); + s.Save(parent); + tx.Commit(); + return parent; + } + } + } + + protected IParentWithCollection CreateParentWithOneChild(string parentName, string ChildName) + { + using (ISession s = OpenSession()) + { + using (ITransaction tx = s.BeginTransaction()) + { + IParentWithCollection parent = CreateParent(parentName); + parent.NewChildren(CreateCollection()); + parent.AddChild(ChildName); + s.Save(parent); + tx.Commit(); + return parent; + } + } + } + + protected void CheckResult(CollectionListeners listeners, CollectionListeners.IListener listenerExpected, + IParentWithCollection parent, int index) + { + CheckResult(listeners, listenerExpected, parent, parent.Children, index); + } + + protected void CheckResult(CollectionListeners listeners, CollectionListeners.IListener listenerExpected, + IEntity ownerExpected, object collExpected, int index) + { + Assert.That(listeners.ListenersCalled[index], Is.SameAs(listenerExpected)); + Assert.That(((AbstractCollectionEvent) listeners.Events[index]).AffectedOwnerOrNull, Is.SameAs(ownerExpected)); + Assert.That(((AbstractCollectionEvent) listeners.Events[index]).AffectedOwnerIdOrNull, Is.EqualTo(ownerExpected.Id)); + Assert.That(((AbstractCollectionEvent) listeners.Events[index]).GetAffectedOwnerEntityName(), + Is.EqualTo(ownerExpected.GetType().FullName)); + Assert.That(((AbstractCollectionEvent) listeners.Events[index]).Collection, Is.SameAs(collExpected)); + } + + protected void CheckNumberOfResults(CollectionListeners listeners, int nEventsExpected) + { + Assert.That(listeners.ListenersCalled.Count, Is.EqualTo(nEventsExpected)); + Assert.That(listeners.Events.Count, Is.EqualTo(nEventsExpected)); + } + + protected void CheckResult(CollectionListeners listeners, CollectionListeners.IListener listenerExpected, + ChildWithBidirectionalManyToMany child, int index) + { + CheckResult(listeners, listenerExpected, child, child.Parents, index); + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/Events/Collections/AbstractParentWithCollection.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Events/Collections/AbstractParentWithCollection.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Events/Collections/AbstractParentWithCollection.cs 2008-08-20 20:07:55 UTC (rev 3721) @@ -0,0 +1,90 @@ +using System.Collections.Generic; + +namespace NHibernate.Test.Events.Collections +{ + public abstract class AbstractParentWithCollection : IParentWithCollection + { + private ICollection<IChild> children; + private long id; + private string name; + protected AbstractParentWithCollection() {} + + protected AbstractParentWithCollection(string name) + { + this.name = name; + } + + #region IParentWithCollection Members + + public virtual long Id + { + get { return id; } + set { id = value; } + } + + public virtual void NewChildren(ICollection<IChild> collection) + { + Children = collection; + } + + public abstract IChild CreateChild(string name); + + public virtual string Name + { + get { return name; } + set { name = value; } + } + + public virtual ICollection<IChild> Children + { + get { return children; } + set { children = value; } + } + + public virtual IChild AddChild(string childName) + { + IChild c = CreateChild(childName); + AddChild(c); + return c; + } + + public virtual void AddChild(IChild child) + { + if (child != null) + { + children.Add(child); + } + } + + public virtual void AddAllChildren(ICollection<IChild> children) + { + foreach (IChild child in children) + { + this.children.Add(child); + } + } + + public virtual void RemoveChild(IChild child) + { + children.Remove(child); + } + + public virtual void RemoveAllChildren(ICollection<IChild> children) + { + foreach (IChild child in children) + { + this.children.Remove(child); + } + } + + public virtual void ClearChildren() + { + if (children != null) + { + children.Clear(); + } + } + + #endregion + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/AbstractAssociationCollectionEventFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/AbstractAssociationCollectionEventFixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/AbstractAssociationCollectionEventFixture.cs 2008-08-20 20:07:55 UTC (rev 3721) @@ -0,0 +1,39 @@ +using NHibernate.Test.Events.Collections.Association.Bidirectional.ManyToMany; +using NUnit.Framework; + +namespace NHibernate.Test.Events.Collections.Association +{ + public abstract class AbstractAssociationCollectionEventFixture : AbstractCollectionEventFixture + { + [Test] + public void DeleteParentButNotChild() + { + CollectionListeners listeners = new CollectionListeners(sessions); + IParentWithCollection parent = CreateParentWithOneChild("parent", "child"); + ChildEntity child = (ChildEntity) GetFirstChild(parent.Children); + listeners.Clear(); + ISession s = OpenSession(); + ITransaction tx = s.BeginTransaction(); + parent = (IParentWithCollection) s.Get(parent.GetType(), parent.Id); + child = (ChildEntity) s.Get(child.GetType(), child.Id); + parent.RemoveChild(child); + s.Delete(parent); + tx.Commit(); + s.Close(); + int index = 0; + CheckResult(listeners, listeners.InitializeCollection, parent, index++); + if (child is ChildWithBidirectionalManyToMany) + { + CheckResult(listeners, listeners.InitializeCollection, (ChildWithBidirectionalManyToMany) child, index++); + } + CheckResult(listeners, listeners.PreCollectionRemove, parent, index++); + CheckResult(listeners, listeners.PostCollectionRemove, parent, index++); + if (child is ChildWithBidirectionalManyToMany) + { + CheckResult(listeners, listeners.PreCollectionUpdate, (ChildWithBidirectionalManyToMany) child, index++); + CheckResult(listeners, listeners.PostCollectionUpdate, (ChildWithBidirectionalManyToMany) child, index++); + } + CheckNumberOfResults(listeners, index); + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/ManyToMany/BidirectionalManyToManyBagToSetCollectionEventFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/ManyToMany/BidirectionalManyToManyBagToSetCollectionEventFixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/ManyToMany/BidirectionalManyToManyBagToSetCollectionEventFixture.cs 2008-08-20 20:07:55 UTC (rev 3721) @@ -0,0 +1,25 @@ +using System.Collections; +using System.Collections.Generic; +using NUnit.Framework; + +namespace NHibernate.Test.Events.Collections.Association.Bidirectional.ManyToMany +{ + [TestFixture, Ignore("Need some more check for timeouts.")] + public class BidirectionalManyToManyBagToSetCollectionEventFixture : AbstractAssociationCollectionEventFixture + { + protected override IList Mappings + { + get { return new string[] { "Events.Collections.Association.Bidirectional.ManyToMany.BidirectionalManyToManyBagToSetMapping.hbm.xml" }; } + } + + public override IParentWithCollection CreateParent(string name) + { + return new ParentWithBidirectionalManyToMany(name); + } + + public override ICollection<IChild> CreateCollection() + { + return new List<IChild>(); + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/ManyToMany/BidirectionalManyToManyBagToSetMapping.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/ManyToMany/BidirectionalManyToManyBagToSetMapping.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/ManyToMany/BidirectionalManyToManyBagToSetMapping.hbm.xml 2008-08-20 20:07:55 UTC (rev 3721) @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" + assembly="NHibernate.Test" + namespace="NHibernate.Test.Events.Collections.Association.Bidirectional.ManyToMany"> + + <class name="ParentWithBidirectionalManyToMany" table="PARENT"> + <id name="Id" column="ID" type="long"> + <generator class="native"/> + </id> + <bag name="Children" table="PARENT_CHILD" inverse="false" cascade="all"> + <key column="parent_id"/> + <many-to-many column="child_id" class="ChildWithBidirectionalManyToMany"/> + </bag> + </class> + + <class name="ChildWithBidirectionalManyToMany" table="CHILD"> + <id name="Id" column="ID" type="long"> + <generator class="native"/> + </id> + <property name="Name" column="NAME" type="string"/> + <set name="Parents" table="PARENT_CHILD" inverse="true"> + <key column="child_id"/> + <many-to-many column="parent_id" class="ParentWithBidirectionalManyToMany"/> + </set> + </class> + +</hibernate-mapping> Added: trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bidirectional/ManyToMany/BidirectionalManyToManySetToSetCollectionEventFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/Events/Collections/Association/Bid... [truncated message content] |