From: <fab...@us...> - 2009-06-05 14:08:19
|
Revision: 4414 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4414&view=rev Author: fabiomaulo Date: 2009-06-05 13:50:25 +0000 (Fri, 05 Jun 2009) Log Message: ----------- Fix NH-1601 Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Event/Default/DefaultRefreshEventListener.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1601/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1601/Fixture1.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1601/Fixture2.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1601/Mappings.hbm.xml trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1601/Project.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1601/Scenario.cs Modified: trunk/nhibernate/src/NHibernate/Event/Default/DefaultRefreshEventListener.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Event/Default/DefaultRefreshEventListener.cs 2009-06-05 06:01:33 UTC (rev 4413) +++ trunk/nhibernate/src/NHibernate/Event/Default/DefaultRefreshEventListener.cs 2009-06-05 13:50:25 UTC (rev 4414) @@ -93,6 +93,12 @@ EvictCachedCollections(persister, id, source.Factory); + // NH Different behavior : NH-1601 + // At this point the entity need the real refresh, all elementes of collections are Refreshed, + // the collection state was evicted, but the PersistentCollection (in the entity state) + // is associated with a possible previous session. + new WrapVisitor(source).Process(obj, persister); + string previousFetchProfile = source.FetchProfile; source.FetchProfile = "refresh"; object result = persister.Load(id, obj, @event.LockMode, source); Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1601/Fixture1.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1601/Fixture1.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1601/Fixture1.cs 2009-06-05 13:50:25 UTC (rev 4414) @@ -0,0 +1,137 @@ +using System.Collections.Generic; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.NH1601 +{ + [TestFixture] + public class Fixture1 : BugTestCase + { + /// <summary> + /// Loads the project do not call Count on the list assigned. + /// </summary> + [Test] + public void TestSaveAndLoadWithoutCount() + { + ProjectWithOneList.TestAccessToList = false; + SaveAndLoadProjectWithOneList(); + } + + /// <summary> + /// Refreshes the project do not call Count on the list assigned. + /// </summary> + [Test] + public void TestRefreshWithoutCount() + { + ProjectWithOneList.TestAccessToList = false; + SaveLoadAndRefreshProjectWithOneList(); + } + + /// <summary> + /// Loads the project and when Scenario1 is assigned call Count on the list. + /// </summary> + [Test] + public void TestSaveAndLoadWithCount() + { + ProjectWithOneList.TestAccessToList = true; + SaveAndLoadProjectWithOneList(); + } + + /// <summary> + /// Refreshes the project and when Scenario1 is assigned call Count on the list. + /// </summary> + [Test] + public void TestRefreshWithCount() + { + ProjectWithOneList.TestAccessToList = true; + SaveLoadAndRefreshProjectWithOneList(); + } + + /// <summary> + /// Create and save a Project + /// </summary> + public void SaveAndLoadProjectWithOneList() + { + SaveProject(); + LoadProject(); + } + + /// <summary> + /// Create, save and refresh projects + /// </summary> + public void SaveLoadAndRefreshProjectWithOneList() + { + SaveProject(); + ProjectWithOneList project = LoadProject(); + RefreshProject(project); + } + + public ProjectWithOneList SaveProject( ) + { + ProjectWithOneList project; + + using( ISession session = OpenSession( ) ) + using( ITransaction tx = session.BeginTransaction( ) ) + { + //Create a project scenario + project = new ProjectWithOneList(); + Scenario scenario = new Scenario( ); + + //Add the scenario to both lists + project.ScenarioList1.Add(scenario); + + //Set the primary key on the project + project.Name = "Test"; + + //Save the created project + session.Save( project ); + + tx.Commit( ); + } + return project; + } + + + public ProjectWithOneList LoadProject() + { + ProjectWithOneList project; + using (ISession session = OpenSession()) + using (ITransaction tx = session.BeginTransaction()) + { + //The project is loaded and Scenario1, Scenario2 and Scenario3 properties can be set + //This will succeed regardless of whether the scenario list is accessed during the set + project = session.Get<ProjectWithOneList>("Test"); + + //Commit the transaction and cloase the session + tx.Commit(); + } + return project; + } + + public void RefreshProject(ProjectWithOneList project) + { + + using (ISession session = OpenSession()) + using (ITransaction tx = session.BeginTransaction()) + { + //The project is refreshed and Scenario1, Scenario2 and Scenario3 properties can be set + //This will succeed when the scenario list is set and accessed during the set but only for + //Scenario 2 and Scenario3. It will fail if the scenario list is accessed during the set for Scenario1 + session.Refresh(project); + } + } + + protected override void OnTearDown( ) + { + base.OnTearDown( ); + using( ISession session = OpenSession( ) ) + { + using( ITransaction tx = session.BeginTransaction( ) ) + { + session.Delete(" from ProjectWithOneList"); + session.Delete( "from Scenario" ); + tx.Commit( ); + } + } + } + } +} Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1601/Fixture2.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1601/Fixture2.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1601/Fixture2.cs 2009-06-05 13:50:25 UTC (rev 4414) @@ -0,0 +1,146 @@ +using System.Collections.Generic; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.NH1601 +{ + [TestFixture] + public class Fixture2 : BugTestCase + { + /// <summary> + /// Loads the project and when Scenario2 and Scenario3 are set calls Count on the list assigned. + /// </summary> + [Test] + public void TestSaveAndLoadWithTwoCounts() + { + Project.TestAccessToList = false; + SaveAndLoadProject(); + } + + /// <summary> + /// Refreshes the project and when Scenario2 and Scenario3 are set calls Count on the list assigned. + /// </summary> + [Test] + public void TestRefreshWithTwoCounts() + { + Project.TestAccessToList = false; + SaveLoadAndRefreshProject(); + } + + /// <summary> + /// Loads the project and when Scenario1, Scenario2 and Scenario3 are set calls Count on the list assigned. + /// </summary> + [Test] + public void TestTestSaveAndLoadWithThreeCounts() + { + Project.TestAccessToList = true; + SaveAndLoadProject(); + } + + /// <summary> + /// Refreshes the project and when Scenario1, Scenario2 and Scenario3 are set calls Count on the list assigned. + /// Throws an exception on calling Count on Scenario1. + /// </summary> + [Test] + public void TestRefreshWithThreeCounts() + { + Project.TestAccessToList = true; + SaveLoadAndRefreshProject(); + } + + + /// <summary> + /// Create and save a Project + /// </summary> + public void SaveAndLoadProject() + { + SaveProject(); + LoadProject(); + } + + /// <summary> + /// Create, save and refresh projects + /// </summary> + public void SaveLoadAndRefreshProject() + { + SaveProject(); + Project project = LoadProject(); + RefreshProject(project); + } + + + public Project SaveProject( ) + { + Project project; + + using( ISession session = OpenSession( ) ) + using( ITransaction tx = session.BeginTransaction( ) ) + { + //Create a project scenario + project = new Project( ); + Scenario scenario1 = new Scenario( ); + Scenario scenario2 = new Scenario(); + Scenario scenario3 = new Scenario(); + + + //Add the scenario to all lists + project.ScenarioList1.Add(scenario1); + project.ScenarioList2.Add(scenario2); + project.ScenarioList3.Add(scenario3); + + + //Set the primary key on the project + project.Name = "Test"; + + //Save the created project + session.Save( project ); + + tx.Commit( ); + } + return project; + } + + + public Project LoadProject() + { + Project project; + using (ISession session = OpenSession()) + using (ITransaction tx = session.BeginTransaction()) + { + //The project is loaded and Scenario1, Scenario2 and Scenario3 properties can be set + //This will succeed regardless of whether the scenario list is accessed during the set + project = session.Get<Project>("Test"); + + //Commit the transaction and cloase the session + tx.Commit(); + } + return project; + } + + public void RefreshProject(Project project) + { + + using (ISession session = OpenSession()) + using (ITransaction tx = session.BeginTransaction()) + { + //The project is refreshed and Scenario1, Scenario2 and Scenario3 properties can be set + //This will succeed when the scenario list is set and accessed during the set but only for + //Scenario 2 and Scenario3. It will fail if the scenario list is accessed during the set for Scenario1 + session.Refresh(project); + } + } + + protected override void OnTearDown( ) + { + base.OnTearDown( ); + using( ISession session = OpenSession( ) ) + { + using( ITransaction tx = session.BeginTransaction( ) ) + { + session.Delete( "from Project" ); + session.Delete( "from Scenario" ); + tx.Commit( ); + } + } + } + } +} Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1601/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1601/Mappings.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1601/Mappings.hbm.xml 2009-06-05 13:50:25 UTC (rev 4414) @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" + assembly="NHibernate.Test" + namespace="NHibernate.Test.NHSpecificTest.NH1601" + default-lazy="false"> + + <class name="Project" table="Project" lazy="false"> + <id name="Name" type="string"> + <column name="id"/> + <generator class="assigned" /> + </id> + + <!--First mapped list fails on refresh when setter accesses list--> + <list name="ScenarioList1" cascade="all" lazy="false"> + <key column="ScenarioList1ID"/> + <index column ="ScenarioList1Index"/> + <one-to-many class="Scenario"/> + </list> + <!--Subsequent mapped lists succeed on refresh when setter accesses list--> + <list name="ScenarioList2" cascade="all" lazy="false"> + <key column="ScenarioList2ID"/> + <index column ="ScenarioList2Index"/> + <one-to-many class="Scenario"/> + </list> + <list name="ScenarioList3" cascade="all" lazy="false"> + <key column="ScenarioList3ID"/> + <index column ="ScenarioList3Index"/> + <one-to-many class="Scenario"/> + </list> + </class> + + <class name="ProjectWithOneList" table="ProjectWithOneList" lazy="false"> + <id name="Name" type="string"> + <column name="id"/> + <generator class="assigned" /> + </id> + + <!-- First mapped list fails on refresh when setter accesses list --> + <list name="ScenarioList1" cascade="all" lazy="false"> + <key column="ScenarioListPWOLID"/> + <index column ="ScenarioListPWOLIndex"/> + <one-to-many class="Scenario"/> + </list> + + </class> + + <class name="Scenario" table="Scenario" lazy="false"> + <id type="Int32" name="id"> + <column name="ScenarioID"/> + <generator class="increment" /> + </id> + </class> + +</hibernate-mapping> Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1601/Project.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1601/Project.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1601/Project.cs 2009-06-05 13:50:25 UTC (rev 4414) @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using System.Text; +using NUnit.Framework; + + +namespace NHibernate.Test.NHSpecificTest.NH1601 +{ + public class Project + { + public static bool TestAccessToList = false; + + /// <summary> + /// NHibernate sets this property on load and refresh. It fails in refresh if + /// the value is accessed during the set. This occurs on this list because it is + /// mapped first in the XML mapping. + /// </summary> + public IList<Scenario> ScenarioList1 + { + get { return scenarioList1; } + set { + scenarioList1 = value; + if (TestAccessToList) + { int i = scenarioList1.Count;} + } + } + + public IList<Scenario> ScenarioList2 + { + get { return scenarioList2; } + set { scenarioList2 = value; + int i = scenarioList2.Count; + } + } + + public IList<Scenario> ScenarioList3 + { + get { return scenarioList3; } + set + { + scenarioList3 = value; + int i = scenarioList3.Count; + } + } + + public Project( ) + { + } + + private string name; + + public string Name + { + get { return name; } + set { name = value;} + } + + private IList<Scenario> scenarioList1 = new List<Scenario>(); + private IList<Scenario> scenarioList2 = new List<Scenario>(); + private IList<Scenario> scenarioList3 = new List<Scenario>(); + + + } + public class ProjectWithOneList + { + public static bool TestAccessToList = false; + + /// <summary> + /// NHibernate sets this property on load and refresh. It fails in refresh if + /// the value is accessed during the set. This occurs on this list because it is + /// mapped first in the XML mapping. + /// </summary> + public IList<Scenario> ScenarioList1 + { + get { return scenarioList1; } + set + { + scenarioList1 = value; + if (TestAccessToList) + { int i = scenarioList1.Count; } + } + } + + public ProjectWithOneList() + { + } + + private string name; + + public string Name + { + get { return name; } + set { name = value; } + } + + private IList<Scenario> scenarioList1 = new List<Scenario>(); + + } +} Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1601/Scenario.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1601/Scenario.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1601/Scenario.cs 2009-06-05 13:50:25 UTC (rev 4414) @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NHibernate.Test.NHSpecificTest.NH1601 +{ + + public class Scenario + { + + protected int _id; + + + public virtual int id + { + get { return _id; } + set { _id = value; } + } + + + public Scenario( ) + { + } + + } + +} Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2009-06-05 06:01:33 UTC (rev 4413) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2009-06-05 13:50:25 UTC (rev 4414) @@ -405,6 +405,10 @@ <Compile Include="NHSpecificTest\NH1391\SivasKangal.cs" /> <Compile Include="NHSpecificTest\NH1393\Fixture.cs" /> <Compile Include="NHSpecificTest\NH1393\Person.cs" /> + <Compile Include="NHSpecificTest\NH1601\Fixture1.cs" /> + <Compile Include="NHSpecificTest\NH1601\Fixture2.cs" /> + <Compile Include="NHSpecificTest\NH1601\Project.cs" /> + <Compile Include="NHSpecificTest\NH1601\Scenario.cs" /> <Compile Include="NHSpecificTest\NH1617\Fixture.cs" /> <Compile Include="NHSpecificTest\NH1617\Order.cs" /> <Compile Include="NHSpecificTest\NH1617\User.cs" /> @@ -1877,6 +1881,7 @@ <EmbeddedResource Include="CacheTest\EntityWithFilters.xml" /> <EmbeddedResource Include="Classic\EntityWithLifecycle.hbm.xml" /> <Content Include="DynamicEntity\package.html" /> + <EmbeddedResource Include="NHSpecificTest\NH1601\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH1617\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH1810\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH1092\Mappings.hbm.xml" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |