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