|
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] |