|
From: <fab...@us...> - 2009-06-11 07:00:51
|
Revision: 4453
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4453&view=rev
Author: fabiomaulo
Date: 2009-06-11 07:00:45 +0000 (Thu, 11 Jun 2009)
Log Message:
-----------
Fix NH-1810 (thanks to Lee Henson for all his work around the issue)
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Collection/PersistentSet.cs
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1810/Fixture.cs
Modified: trunk/nhibernate/src/NHibernate/Collection/PersistentSet.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Collection/PersistentSet.cs 2009-06-11 04:36:17 UTC (rev 4452)
+++ trunk/nhibernate/src/NHibernate/Collection/PersistentSet.cs 2009-06-11 07:00:45 UTC (rev 4453)
@@ -13,6 +13,109 @@
namespace NHibernate.Collection
{
+ internal interface ISetSnapshot<T>: ICollection<T>, ICollection
+ {
+ T this[T element]{ get;}
+ }
+
+ [Serializable]
+ internal class SetSnapShot<T> : ISetSnapshot<T>
+ {
+ private readonly List<T> elements;
+ public SetSnapShot()
+ {
+ elements = new List<T>();
+ }
+
+ public SetSnapShot(int capacity)
+ {
+ elements = new List<T>(capacity);
+ }
+
+ public SetSnapShot(IEnumerable<T> collection)
+ {
+ elements = new List<T>(collection);
+ }
+
+ public IEnumerator<T> GetEnumerator()
+ {
+ return elements.GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+
+ public void Add(T item)
+ {
+ elements.Add(item);
+ }
+
+ public void Clear()
+ {
+ throw new InvalidOperationException();
+ }
+
+ public bool Contains(T item)
+ {
+ return elements.Contains(item);
+ }
+
+ public void CopyTo(T[] array, int arrayIndex)
+ {
+ elements.CopyTo(array, arrayIndex);
+ }
+
+ public bool Remove(T item)
+ {
+ throw new InvalidOperationException();
+ }
+
+ public void CopyTo(Array array, int index)
+ {
+ ((ICollection)elements).CopyTo(array, index);
+ }
+
+ int ICollection.Count
+ {
+ get { return elements.Count; }
+ }
+
+ public object SyncRoot
+ {
+ get { return ((ICollection)elements).SyncRoot; }
+ }
+
+ public bool IsSynchronized
+ {
+ get { return ((ICollection)elements).IsSynchronized; }
+ }
+
+ int ICollection<T>.Count
+ {
+ get { return elements.Count; }
+ }
+
+ public bool IsReadOnly
+ {
+ get { return ((ICollection<T>)elements).IsReadOnly; }
+ }
+
+ public T this[T element]
+ {
+ get
+ {
+ var idx = elements.IndexOf(element);
+ if(idx >=0)
+ {
+ return elements[idx];
+ }
+ return default(T);
+ }
+ }
+ }
+
/// <summary>
/// .NET has no design equivalent for Java's Set so we are going to use the
/// Iesi.Collections library. This class is internal to NHibernate and shouldn't
@@ -78,28 +181,30 @@
{
EntityMode entityMode = Session.EntityMode;
- //if (set==null) return new Set(session);
- Hashtable clonedSet = new Hashtable(set.Count);
+ // NH Different behavior : for NH-1810 and the way is working the possible underlining collection
+ // the Snapshot is represented using a List<T>
+ // (perhaps it has less performance then IDictionary but it is working)
+ // TODO : should use ever underlining collection type or something to have same performace and same order
+ var clonedSet = new SetSnapShot<object>(set.Count);
foreach (object current in set)
{
object copied = persister.ElementType.DeepCopy(current, entityMode, persister.Factory);
- clonedSet[copied] = copied;
+ clonedSet.Add(copied);
}
return clonedSet;
}
public override ICollection GetOrphans(object snapshot, string entityName)
{
- IDictionary sn = (IDictionary) snapshot;
- // NH Different implementation : sn.Keys return a new collection we don't need "re-new"
- return GetOrphans(sn.Keys, set, entityName, Session);
+ var sn = new SetSnapShot<object>((IEnumerable<object>)snapshot);
+ return GetOrphans(sn, set, entityName, Session);
}
public override bool EqualsSnapshot(ICollectionPersister persister)
{
IType elementType = persister.ElementType;
- IDictionary snapshot = (IDictionary) GetSnapshot();
- if (snapshot.Count != set.Count)
+ var snapshot = (ISetSnapshot<object>)GetSnapshot();
+ if (((ICollection)snapshot).Count != set.Count)
{
return false;
}
@@ -118,7 +223,7 @@
public override bool IsSnapshotEmpty(object snapshot)
{
- return ((IDictionary) snapshot).Count == 0;
+ return ((ICollection)snapshot).Count == 0;
}
public override void BeforeInitialize(ICollectionPersister persister, int anticipatedSize)
@@ -212,9 +317,9 @@
public override IEnumerable GetDeletes(ICollectionPersister persister, bool indexIsFormula)
{
IType elementType = persister.ElementType;
- IDictionary sn = (IDictionary) GetSnapshot();
- List<object> deletes = new List<object>(sn.Count);
- foreach (object obj in sn.Keys)
+ var sn = (ISetSnapshot<object>)GetSnapshot();
+ var deletes = new List<object>(((ICollection)sn).Count);
+ foreach (object obj in sn)
{
if (!set.Contains(obj))
{
@@ -237,7 +342,7 @@
public override bool NeedsInserting(object entry, int i, IType elemType)
{
- IDictionary sn = (IDictionary) GetSnapshot();
+ var sn = (ISetSnapshot<object>) GetSnapshot();
object oldKey = sn[entry];
// note that it might be better to iterate the snapshot but this is safe,
// assuming the user implements equals() properly, as required by the PersistentSet
Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1810/Fixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1810/Fixture.cs 2009-06-11 04:36:17 UTC (rev 4452)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1810/Fixture.cs 2009-06-11 07:00:45 UTC (rev 4453)
@@ -4,7 +4,7 @@
namespace NHibernate.Test.NHSpecificTest.NH1810
{
- [TestFixture, Ignore("To investigate.")]
+ [TestFixture]
public class Fixture : BugTestCase
{
// The problem is the same using a default sort="natural" collection for Children
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|