From: <jul...@us...> - 2010-09-14 13:37:59
|
Revision: 5184 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5184&view=rev Author: julian-maughan Date: 2010-09-14 13:37:52 +0000 (Tue, 14 Sep 2010) Log Message: ----------- Fixed bug whereby PersistentGenericIdentifierBag instantiates a List<T> type when a user-configured collection type is expected (ref. NH-2278). Also, added back a comment that was inadvertently removed from PersistenIdentifierBag.ReadFrom. Credit to Patrick Earl. Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Collection/Generic/PersistentGenericIdentifierBag.cs trunk/nhibernate/src/NHibernate/Collection/PersistentIdentifierBag.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2278/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2278/CustomA.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2278/CustomIdentifierBagType.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2278/CustomList.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2278/CustomPersistentIdentifierBag.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2278/Fixture.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2278/ICustomList.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2278/Mappings.hbm.xml Modified: trunk/nhibernate/src/NHibernate/Collection/Generic/PersistentGenericIdentifierBag.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Collection/Generic/PersistentGenericIdentifierBag.cs 2010-09-13 16:31:46 UTC (rev 5183) +++ trunk/nhibernate/src/NHibernate/Collection/Generic/PersistentGenericIdentifierBag.cs 2010-09-14 13:37:52 UTC (rev 5184) @@ -37,7 +37,9 @@ * from the better performance the use of generic implementation have. */ private IList<T> gvalues; + public PersistentIdentifierBag() {} + public PersistentIdentifierBag(ISessionImplementor session) : base(session) {} public PersistentIdentifierBag(ISessionImplementor session, ICollection<T> coll) : base(session, coll as ICollection) @@ -64,7 +66,7 @@ public override void BeforeInitialize(ICollectionPersister persister, int anticipatedSize) { identifiers = anticipatedSize <= 0 ? new Dictionary<int, object>() : new Dictionary<int, object>(anticipatedSize + 1); - InternalValues = anticipatedSize <= 0 ? new List<T>() : new List<T>(anticipatedSize); + InternalValues = (IList<T>)persister.CollectionType.Instantiate(anticipatedSize); } #region IList<T> Members Modified: trunk/nhibernate/src/NHibernate/Collection/PersistentIdentifierBag.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Collection/PersistentIdentifierBag.cs 2010-09-13 16:31:46 UTC (rev 5183) +++ trunk/nhibernate/src/NHibernate/Collection/PersistentIdentifierBag.cs 2010-09-14 13:37:52 UTC (rev 5184) @@ -221,6 +221,8 @@ { object element = persister.ReadElement(reader, owner, descriptor.SuffixedElementAliases, Session); object id = persister.ReadIdentifier(reader, descriptor.SuffixedIdentifierAlias, Session); + + // eliminate duplication if loaded in a cartesian product if (!identifiers.ContainsValue(id)) { identifiers[values.Count] = id; Property changes on: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2278 ___________________________________________________________________ Added: bugtraq:url + http://jira.nhibernate.org/browse/%BUGID% Added: bugtraq:logregex + NH-\d+ Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2278/CustomA.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2278/CustomA.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2278/CustomA.cs 2010-09-14 13:37:52 UTC (rev 5184) @@ -0,0 +1,32 @@ +using System; +using System.Collections; + +namespace NHibernate.Test.NHSpecificTest.NH2278 +{ + public class CustomA + { + private int? _id; + private string _name; + private ICustomList<string> _items; + + public CustomA() { } + + public int? Id + { + get { return _id; } + set { _id = value; } + } + + public string Name + { + get { return _name; } + set { _name = value; } + } + + public ICustomList<string> Items + { + get { return _items; } + set { _items = value; } + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2278/CustomIdentifierBagType.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2278/CustomIdentifierBagType.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2278/CustomIdentifierBagType.cs 2010-09-14 13:37:52 UTC (rev 5184) @@ -0,0 +1,59 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NHibernate.Collection; +using NHibernate.Engine; +using NHibernate.Persister.Collection; +using NHibernate.UserTypes; + +namespace NHibernate.Test.NHSpecificTest.NH2278 +{ + public class CustomIdentifierBagType<T> : IUserCollectionType + { + #region IUserCollectionType Members + + public bool Contains(object collection, object entity) + { + return ((IList<T>)collection).Contains((T)entity); + } + + public IEnumerable GetElements(object collection) + { + return (IEnumerable)collection; + } + + public object IndexOf(object collection, object entity) + { + return ((IList<T>)collection).IndexOf((T)entity); + } + + public object ReplaceElements(object original, object target, ICollectionPersister persister, object owner, IDictionary copyCache, ISessionImplementor session) + { + IList<T> result = (IList<T>)target; + result.Clear(); + foreach (object item in ((IEnumerable)original)) + result.Add((T)item); + return result; + } + + // return an instance of the inner collection type + public object Instantiate(int anticipatedSize) + { + return new CustomList<T>(); + } + + public IPersistentCollection Instantiate(ISessionImplementor session, ICollectionPersister persister) + { + return new CustomPersistentIdentifierBag<T>(session); + } + + public IPersistentCollection Wrap(ISessionImplementor session, object collection) + { + return new CustomPersistentIdentifierBag<T>(session, (ICollection<T>)collection); + } + + #endregion + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2278/CustomList.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2278/CustomList.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2278/CustomList.cs 2010-09-14 13:37:52 UTC (rev 5184) @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace NHibernate.Test.NHSpecificTest.NH2278 +{ + public class CustomList<T> : List<T>, ICustomList<T> + { + } +} Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2278/CustomPersistentIdentifierBag.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2278/CustomPersistentIdentifierBag.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2278/CustomPersistentIdentifierBag.cs 2010-09-14 13:37:52 UTC (rev 5184) @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NHibernate.Collection; +using NHibernate.Collection.Generic; +using NHibernate.Engine; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.NH2278 +{ + public class CustomPersistentIdentifierBag<T> : PersistentIdentifierBag<T>, ICustomList<T> + { + public CustomPersistentIdentifierBag(ISessionImplementor session) + : base(session) { } + + public CustomPersistentIdentifierBag(ISessionImplementor session, ICollection<T> coll) + : base(session, coll) { } + + public override bool AfterInitialize(NHibernate.Persister.Collection.ICollectionPersister persister) + { + Assert.That(InternalValues, Is.InstanceOf<CustomList<string>>()); + return base.AfterInitialize(persister); + } + } +} Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2278/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2278/Fixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2278/Fixture.cs 2010-09-14 13:37:52 UTC (rev 5184) @@ -0,0 +1,55 @@ +using System; +using System.Collections; + +using NUnit.Framework; +using System.Collections.Generic; + +namespace NHibernate.Test.NHSpecificTest.NH2278 +{ + [TestFixture] + public class Fixture : BugTestCase + { + protected override void OnTearDown() + { + using( ISession s = sessions.OpenSession() ) + { + s.Delete( "from CustomA" ); + s.Flush(); + } + } + + [Test] + public void CustomIdBag() + { + CustomA a = new CustomA(); + a.Name = "first generic type"; + a.Items = new CustomList<string>(); + a.Items.Add( "first string" ); + a.Items.Add( "second string" ); + + ISession s = OpenSession(); + s.SaveOrUpdate(a); + s.Flush(); + s.Close(); + + Assert.That(a.Id, Is.Not.Null); + Assert.That(a.Items[0], Is.StringMatching("first string")); + + s = OpenSession(); + a = s.Load<CustomA>(a.Id); + + Assert.That(a.Items, Is.InstanceOf<CustomPersistentIdentifierBag<string>>()); + + Assert.That(a.Items[0], Is.StringMatching("first string"), "first item should be 'first string'"); + Assert.That(a.Items[1], Is.StringMatching("second string"), "second item should be 'second string'"); + + // ensuring the correct generic type was constructed + a.Items.Add("third string"); + Assert.That(a.Items.Count, Is.EqualTo(3), "3 items in the list now"); + + a.Items[1] = "new second string"; + s.Flush(); + s.Close(); + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2278/ICustomList.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2278/ICustomList.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2278/ICustomList.cs 2010-09-14 13:37:52 UTC (rev 5184) @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace NHibernate.Test.NHSpecificTest.NH2278 +{ + public interface ICustomList<T> : IList<T> + { + } +} Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2278/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2278/Mappings.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2278/Mappings.hbm.xml 2010-09-14 13:37:52 UTC (rev 5184) @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping + xmlns="urn:nhibernate-mapping-2.2" + assembly="NHibernate.Test" + namespace="NHibernate.Test.NHSpecificTest.NH2278"> + + <class name="CustomA" table="customa" lazy="false"> + + <id name="Id" column="id" unsaved-value="null"> + <generator class="native" /> + </id> + + <property name="Name" column="aname" /> + + <idbag + name="Items" + cascade="all-delete-orphan" + collection-type="NHibernate.Test.NHSpecificTest.NH2278.CustomIdentifierBagType`1[[System.String, mscorlib]], NHibernate.Test"> + <collection-id type="Int32" column="item_id"> + <generator class="increment" /> + </collection-id> + <key column="a_id" /> + <element type="string" /> + </idbag> + + </class> + +</hibernate-mapping> Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-09-13 16:31:46 UTC (rev 5183) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2010-09-14 13:37:52 UTC (rev 5184) @@ -465,6 +465,12 @@ <Compile Include="NHSpecificTest\NH2245\Model.cs" /> <Compile Include="NHSpecificTest\NH2266\Domain.cs" /> <Compile Include="NHSpecificTest\NH2266\Fixture.cs" /> + <Compile Include="NHSpecificTest\NH2278\CustomA.cs" /> + <Compile Include="NHSpecificTest\NH2278\CustomIdentifierBagType.cs" /> + <Compile Include="NHSpecificTest\NH2278\CustomList.cs" /> + <Compile Include="NHSpecificTest\NH2278\CustomPersistentIdentifierBag.cs" /> + <Compile Include="NHSpecificTest\NH2278\Fixture.cs" /> + <Compile Include="NHSpecificTest\NH2278\ICustomList.cs" /> <Compile Include="NHSpecificTest\NH2279\A.cs" /> <Compile Include="NHSpecificTest\NH2279\B.cs" /> <Compile Include="NHSpecificTest\NH2279\C.cs" /> @@ -1759,6 +1765,7 @@ <EmbeddedResource Include="NHSpecificTest\NH2279\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2111\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH2322\Mappings.hbm.xml" /> + <EmbeddedResource Include="NHSpecificTest\NH2278\Mappings.hbm.xml" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\NHibernate.ByteCode.Castle\NHibernate.ByteCode.Castle.csproj"> @@ -2604,6 +2611,7 @@ </ItemGroup> <ItemGroup> <Folder Include="NHSpecificTest\NH2111" /> + <Folder Include="NHSpecificTest\NH2278" /> <Folder Include="NHSpecificTest\NH2279" /> <Folder Include="NHSpecificTest\NH2322" /> <Folder Include="Properties\" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |