From: <fab...@us...> - 2009-01-02 14:37:29
|
Revision: 3969 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3969&view=rev Author: fabiomaulo Date: 2009-01-02 14:37:21 +0000 (Fri, 02 Jan 2009) Log Message: ----------- Test for NH-1612 Modified Paths: -------------- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1612/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1612/Area.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1612/AreaStatistics.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1612/City.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1612/Country.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1612/Mappings.hbm.xml trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1612/MonetaryValue.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1612/NativeSqlCollectionLoaderFixture.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1612/Person.cs Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1612/Area.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1612/Area.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1612/Area.cs 2009-01-02 14:37:21 UTC (rev 3969) @@ -0,0 +1,42 @@ +using System.Collections.Generic; + +namespace NHibernate.Test.NHSpecificTest.NH1612 +{ + public abstract class Area + { + public virtual string Code { get; private set; } + public virtual string Name { get; private set; } + public virtual int Version { get; private set; } + public virtual IDictionary<int, AreaStatistics> Statistics { get; private set; } + + protected Area() {} + + protected Area(string code, string name) + { + Code = code; + Name = name; + Statistics = new Dictionary<int, AreaStatistics>(); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(this, obj)) + { + return true; + } + + var other = obj as Area; + if (ReferenceEquals(obj, null)) + { + return false; + } + + return GetType() == other.GetType() && Code == other.Code; + } + + public override int GetHashCode() + { + return (Code ?? string.Empty).GetHashCode() ^ GetType().GetHashCode(); + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1612/AreaStatistics.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1612/AreaStatistics.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1612/AreaStatistics.cs 2009-01-02 14:37:21 UTC (rev 3969) @@ -0,0 +1,59 @@ +using System.Text; + +namespace NHibernate.Test.NHSpecificTest.NH1612 +{ + public class AreaStatistics + { + public virtual MonetaryValue? GDP { get; set; } + public virtual int? CitizenCount { get; set; } + public virtual Person Reporter { get; set; } + + public override bool Equals(object obj) + { + if (ReferenceEquals(this, obj)) + { + return true; + } + + var other = obj as AreaStatistics; + if (ReferenceEquals(other, null)) + { + return false; + } + + return CitizenCount == other.CitizenCount && GDP == other.GDP && Reporter == other.Reporter; + } + + public override int GetHashCode() + { + return (CitizenCount ?? 0) ^ GDP.GetHashCode() ^ (Reporter != null ? Reporter.GetHashCode() : 0); + } + + public override string ToString() + { + var sb = new StringBuilder(); + if (CitizenCount.HasValue) + { + sb.Append("CitizenCount: ").Append(CitizenCount); + } + if (GDP.HasValue) + { + if (sb.Length > 0) + { + sb.Append("; "); + } + sb.Append("GDP: ").Append(GDP); + } + if (Reporter != null) + { + if (sb.Length > 0) + { + sb.Append("; "); + } + sb.Append("Reporter: ").Append(Reporter.Name); + } + + return sb.ToString(); + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1612/City.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1612/City.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1612/City.cs 2009-01-02 14:37:21 UTC (rev 3969) @@ -0,0 +1,24 @@ +namespace NHibernate.Test.NHSpecificTest.NH1612 +{ + public class City : Area + { + public virtual Country Country { get; private set; } + + protected City() {} + + public City(string code, string name) : base(code, name) {} + + public virtual void SetParent(Country country) + { + if (Country != null) + { + Country.Cities.Remove(this); + } + Country = country; + if (country != null) + { + country.Cities.Add(this); + } + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1612/Country.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1612/Country.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1612/Country.cs 2009-01-02 14:37:21 UTC (rev 3969) @@ -0,0 +1,18 @@ +using System.Collections.Generic; + +namespace NHibernate.Test.NHSpecificTest.NH1612 +{ + public class Country : Area + { + public virtual IList<string> Routes { get; private set; } + public virtual IList<City> Cities { get; private set; } + + protected Country() {} + + public Country(string code, string name) : base(code, name) + { + Routes = new List<string>(); + Cities = new List<City>(); + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1612/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1612/Mappings.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1612/Mappings.hbm.xml 2009-01-02 14:37:21 UTC (rev 3969) @@ -0,0 +1,306 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" + assembly="NHibernate.Test" + namespace="NHibernate.Test.NHSpecificTest.NH1612" + default-cascade="save-update"> + + <class name="Area" table="areas"> + <id name="Code" column="code" type="String" length="3"> + <generator class="assigned"/> + </id> + <discriminator column="area_type" type="String" length="2" not-null="true" /> + <version name="Version" column="version" type="Int32" generated="never" unsaved-value="0" /> + <property name="Name" column="name" type="String" length="50" not-null="true" /> + <map name="Statistics" table="stats"> + <key column="area_code" /> + <index column="year" type="Int32" /> + <composite-element class="AreaStatistics"> + <property name="CitizenCount" column="citizen_count" type="Int32" /> + <nested-composite-element name="GDP" class="MonetaryValue"> + <property name="CurrencySymbol" column="gdp_currency" type="String" length="3" /> + <property name="Amount" column="gdp_amount" type="double" not-null="false" /> + </nested-composite-element> + <many-to-one name="Reporter" column="reporter_id" class="Person" /> + </composite-element> + <loader query-ref="AreaStatisticsLoader" /> + </map> + + <subclass name="Country" discriminator-value="CO"> + <list name="Routes" table="routes" generic="true"> + <key column="country_code" /> + <index column="route_no" /> + <element column="name" type="String" length="50" /> + <loader query-ref="CountryRouteLoader" /> + </list> + + <bag name="Cities" table="cities" inverse="true" generic="true"> + <key column="country_code" /> + <one-to-many class="City" /> + <loader query-ref="CountryCityLoader" /> + </bag> + </subclass> + + <subclass name="City" discriminator-value="CI"> + <!-- Cascading saves disabled, because it causes exceptions --> + <many-to-one name="Country" column="country_code" class="Country" /> + </subclass> + </class> + + <class name="Person" table="persons"> + <id name="PersonId" column="id"> + <generator class="assigned" /> + </id> + <version name="Version" column="version" type="Int32" generated="never" unsaved-value="0" /> + <property name="Name" type="String" length="100" /> + </class> + + <!-- + Collection loaders + --> + + <sql-query name="CountryRouteLoader" xml:space="preserve"> + <load-collection role="Country.Routes" alias="r" /> + SELECT {r.*} + FROM routes r + WHERE r.country_code = :country_code + </sql-query> + + <sql-query name="CountryCityLoader" xml:space="preserve"> + <load-collection role="Country.Cities" alias="ci" /> + SELECT {ci.*} + FROM areas ci + WHERE ci.country_code = :country_code + AND ci.area_type = 'CI' + </sql-query> + + <sql-query name="CountryStatisticsLoader" xml:space="preserve"> + <load-collection role="Area.Statistics" alias="s"> + <return-property name="key" column="code" /> + <return-property name="index" column="year" /> + <return-property name="element.CitizenCount" column="citizen_count" /> + <return-property name="element.GDP"> + <return-column name="gdp_currency" /> + <return-column name="gdp_amount" /> + </return-property> + <return-property name="element.Reporter" column="reporter_id" /> + </load-collection> + SELECT area_code + , year + , citizen_count + , gdp_currency + , gdp_amount + , reporter_id + FROM stats + WHERE area_code = :area_code + </sql-query> + + + <!-- + Entity queries with non-lazy loading of collections + --> + + <sql-query name="LoadCountryRoutesWithSimpleHbmAliasInjection" xml:space="preserve"> + <return class="Country" alias="c" /> + <return-join alias="r" property="c.Routes" /> + SELECT {c.*} + , {r.*} + FROM areas c + LEFT OUTER JOIN routes r + ON c.code = r.country_code + WHERE c.code = :country_code + </sql-query> + + <sql-query name="LoadCountryRoutesWithCustomAliases" xml:space="preserve"> + <return class="Country" alias="c"> + <return-property name="id" column="code" /> + <return-property name="Version" column="version" /> + <return-property name="Name" column="country_name" /> + </return> + <return-join property="c.Routes" alias="r"> + <return-property name="key" column="country_code" /> + <return-property name="index" column="route_no" /> + <return-property name="element" column="route_name" /> + </return-join> + SELECT c.code + , c.version + , c.name AS country_name + , r.country_code + , r.route_no + , r.name AS route_name + FROM areas c + LEFT OUTER JOIN routes r + ON c.code = r.country_code + WHERE c.code = :country_code + </sql-query> + + <sql-query name="LoadCountryCitiesWithSimpleHbmAliasInjection" xml:space="preserve"> + <return class="Country" alias="co" /> + <return-join property="co.Cities" alias="ci" /> + SELECT {co.*} + , {ci.*} + FROM areas co + LEFT OUTER JOIN areas ci + ON ci.country_code = co.code + AND ci.area_type = 'CI' + WHERE co.code = :country_code + AND co.area_type = 'CO' + </sql-query> + + <sql-query name="LoadCountryCitiesWithComplexHbmAliasInjection" xml:space="preserve"> + <return class="Country" alias="co" /> + <return-join property="co.Cities" alias="ci" /> + SELECT co.code AS {co.id} + , co.version AS {co.Version} + , co.name AS {co.Name} + , ci.country_code AS {ci.key} + , ci.code AS {ci.element} + , ci.code AS {ci.element.id} + , ci.version AS {ci.element.Version} + , ci.name AS {ci.element.Name} + , ci.country_code AS {ci.element.Country} + FROM areas co + LEFT OUTER JOIN areas ci + ON ci.country_code = co.code + AND ci.area_type = 'CI' + WHERE co.code = :country_code + AND co.area_type = 'CO' + </sql-query> + + <sql-query name="LoadCountryCitiesWithCustomAliases" xml:space="preserve"> + <return class="Country" alias="co"> + <return-property name="id" column="country_code" /> + <return-property name="Version" column="country_version" /> + <return-property name="Name" column="country_name" /> + </return> + <return-join property="co.Cities" alias="ci"> + <return-property name="key" column="country_code" /> + <return-property name="element" column="city_code" /> + <return-property name="element.id" column="city_code" /> + <return-property name="element.Version" column="city_version" /> + <return-property name="element.Name" column="city_name" /> + <return-property name="element.Country" column="country_name" /> + </return-join> + SELECT co.code AS country_code + , co.version AS country_version + , co.name AS country_name + , ci.code AS city_code + , ci.version AS city_version + , ci.name AS city_name + FROM areas co + LEFT OUTER JOIN areas ci + ON ci.country_code = co.code + AND ci.area_type = 'CI' + WHERE co.code = :country_code + AND co.area_type = 'CO' + </sql-query> + + <sql-query name="LoadAreaStatisticsWithSimpleHbmAliasInjection" xml:space="preserve"> + <return class="Area" alias="a" /> + <return-join property="a.Statistics" alias="s" /> + SELECT {a.*} + , {s.*} + FROM areas a + LEFT OUTER JOIN stats s + ON a.code = s.area_code + WHERE a.code = :country_code + </sql-query> + + <sql-query name="LoadAreaStatisticsWithComplexHbmAliasInjection" xml:space="preserve"> + <return class="Area" alias="a" /> + <return-join property="a.Statistics" alias="s" /> + SELECT a.code AS {a.id} + , a.area_type AS {a.class} + , a.version AS {a.Version} + , a.name AS {a.Name} + , s.area_code AS {s.key} + , s.year AS {s.index} + , s.citizen_count AS {s.element.CitizenCount} + , s.gdp_currency AS {s.element.GDP.CurrencySymbol} + , s.gdp_amount AS {s.element.GDP.Amount} + , s.reporter_id AS {s.element.Reporter} + FROM areas a + LEFT OUTER JOIN stats s + ON a.code = s.area_code + WHERE a.code = :country_code + </sql-query> + + <sql-query name="LoadAreaStatisticsWithCustomAliases" xml:space="preserve"> + <return class="Area" alias="a"> + <return-discriminator column="area_type" /> + <return-property name="id" column="code" /> + <return-property name="Version" column="version" /> + <return-property name="Name" column="name" /> + </return> + <return-join property="a.Statistics" alias="s"> + <return-property name="key" column="code" /> + <return-property name="index" column="year" /> + <return-property name="element.CitizenCount" column="citizen_count" /> + <return-property name="element.GDP"> + <return-column name="gdp_currency" /> + <return-column name="gdp_amount" /> + </return-property> + <return-property name="element.Reporter" column="reporter_id" /> + </return-join> + SELECT a.code + , a.area_type + , a.version + , a.name + , s.year + , s.citizen_count + , s.gdp_currency + , s.gdp_amount + , s.reporter_id + FROM areas a + LEFT OUTER JOIN stats s + ON a.code = s.area_code + WHERE a.code = :country_code + </sql-query> + + <sql-query name="LoadAreaStatisticsWithFaultyHbmAliasInjection" xml:space="preserve"> + <return class="Area" alias="a" /> + <return-join property="a.Statistics" alias="s" /> + SELECT a.code AS {a.id} + , a.area_type AS {a.class} + , a.version AS {a.Version} + , a.name AS {a.Name} + , s.area_code AS {s.key} + , s.year AS {s.index} + , s.citizen_count AS {s.element.CitizenCountMisspelled} + , s.gdp_currency AS {s.element.GDP.CurrencySymbol} + , s.gdp_amount AS {s.element.GDP.Amount} + FROM areas a + LEFT OUTER JOIN stats s + ON a.code = s.area_code + WHERE a.code = :country_code + </sql-query> + + + <!-- + Update queries + --> + + <sql-query name="UpdateQueryWithoutResults"> + -- NOP + </sql-query> + + + <!-- + Scalar queries + --> + + <sql-query name="ScalarQueryWithDefinedResultset"> + <return-scalar column="result" type="Int32" /> + SELECT 2 AS result + </sql-query> + + <sql-query name="ScalarQueryWithDefinedResultsetButNoResults"> + <!-- Pathetic case, query declares resultset but does not deliver the goods --> + <return-scalar column="dummy" type="Int32" /> + <return class="Area" alias="a" /> + -- NOP + </sql-query> + + <sql-query name="ScalarQueryWithUndefinedResultset"> + SELECT 1 + </sql-query> +</hibernate-mapping> Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1612/MonetaryValue.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1612/MonetaryValue.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1612/MonetaryValue.cs 2009-01-02 14:37:21 UTC (rev 3969) @@ -0,0 +1,51 @@ +namespace NHibernate.Test.NHSpecificTest.NH1612 +{ + public struct MonetaryValue + { + private string _currencySymbol; + private double _amount; + + public MonetaryValue(string currencySymbol, double amount) + { + _currencySymbol = currencySymbol; + _amount = amount; + } + + public string CurrencySymbol + { + get { return _currencySymbol; } + private set { _currencySymbol = value; } + } + + public double Amount + { + get { return _amount; } + private set { _amount = value; } + } + + public static bool operator ==(MonetaryValue left, MonetaryValue right) + { + return left._currencySymbol == right._currencySymbol && left._amount == right._amount; + } + + public static bool operator !=(MonetaryValue left, MonetaryValue right) + { + return !(left == right); + } + + public override bool Equals(object obj) + { + return obj is MonetaryValue ? this == (MonetaryValue) obj : false; + } + + public override int GetHashCode() + { + return (_currencySymbol ?? string.Empty).GetHashCode() ^ _amount.GetHashCode(); + } + + public override string ToString() + { + return string.Format("{0} {1}", _currencySymbol, _amount); + } + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1612/NativeSqlCollectionLoaderFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1612/NativeSqlCollectionLoaderFixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1612/NativeSqlCollectionLoaderFixture.cs 2009-01-02 14:37:21 UTC (rev 3969) @@ -0,0 +1,335 @@ +using System.Collections; +using System.Collections.Generic; +using NUnit.Framework; +using NUnit.Framework.SyntaxHelpers; + +namespace NHibernate.Test.NHSpecificTest.NH1612 +{ + [TestFixture, Ignore("Not fixed yet.")] + public class NativeSqlCollectionLoaderFixture : BugTestCase + { + #region Tests - <return-join> + + [Test] + public void LoadElementsWithWithSimpleHbmAliasInjection() + { + string[] routes = CreateRoutes(); + Country country = LoadCountryWithNativeSQL(CreateCountry(routes), "LoadCountryRoutesWithSimpleHbmAliasInjection"); + + Assert.That(country, Is.Not.Null); + Assert.That(country.Routes, Is.EquivalentTo(routes)); + + // cleanup + using (ISession session = OpenSession()) + { + using (ITransaction tx = session.BeginTransaction()) + { + session.Delete(country); + tx.Commit(); + } + } + } + + [Test] + public void LoadElementsWithExplicitColumnMappings() + { + string[] routes = CreateRoutes(); + Country country = LoadCountryWithNativeSQL(CreateCountry(routes), "LoadCountryRoutesWithCustomAliases"); + Assert.That(country, Is.Not.Null); + Assert.That(country.Routes, Is.EquivalentTo(routes)); + // cleanup + using (ISession session = OpenSession()) + { + using (ITransaction tx = session.BeginTransaction()) + { + session.Delete(country); + tx.Commit(); + } + } + } + + [Test] + public void LoadCompositeElementsWithWithSimpleHbmAliasInjection() + { + IDictionary<int, AreaStatistics> stats = CreateStatistics(); + Country country = LoadCountryWithNativeSQL(CreateCountry(stats), "LoadAreaStatisticsWithSimpleHbmAliasInjection"); + + Assert.That(country, Is.Not.Null); + Assert.That((ICollection) country.Statistics.Keys, Is.EquivalentTo((ICollection) stats.Keys), "Keys"); + Assert.That((ICollection) country.Statistics.Values, Is.EquivalentTo((ICollection) stats.Values), "Elements"); + // cleanup + using (ISession session = OpenSession()) + { + using (ITransaction tx = session.BeginTransaction()) + { + session.Delete(country); + tx.Commit(); + } + } + } + + [Test] + public void LoadCompositeElementsWithWithComplexHbmAliasInjection() + { + IDictionary<int, AreaStatistics> stats = CreateStatistics(); + Country country = LoadCountryWithNativeSQL(CreateCountry(stats), "LoadAreaStatisticsWithComplexHbmAliasInjection"); + + Assert.That(country, Is.Not.Null); + Assert.That((ICollection) country.Statistics.Keys, Is.EquivalentTo((ICollection) stats.Keys), "Keys"); + Assert.That((ICollection) country.Statistics.Values, Is.EquivalentTo((ICollection) stats.Values), "Elements"); + } + + [Test] + public void LoadCompositeElementsWithWithCustomAliases() + { + IDictionary<int, AreaStatistics> stats = CreateStatistics(); + Country country = LoadCountryWithNativeSQL(CreateCountry(stats), "LoadAreaStatisticsWithCustomAliases"); + + Assert.That(country, Is.Not.Null); + Assert.That((ICollection) country.Statistics.Keys, Is.EquivalentTo((ICollection) stats.Keys), "Keys"); + Assert.That((ICollection) country.Statistics.Values, Is.EquivalentTo((ICollection) stats.Values), "Elements"); + } + + [Test] + public void LoadEntitiesWithWithSimpleHbmAliasInjection() + { + City[] cities = CreateCities(); + Country country = LoadCountryWithNativeSQL(CreateCountry(cities), "LoadCountryCitiesWithSimpleHbmAliasInjection"); + Assert.That(country, Is.Not.Null); + Assert.That(country.Cities, Is.EquivalentTo(cities)); + } + + [Test] + public void LoadEntitiesWithComplexHbmAliasInjection() + { + City[] cities = CreateCities(); + Country country = LoadCountryWithNativeSQL(CreateCountry(cities), "LoadCountryCitiesWithComplexHbmAliasInjection"); + Assert.That(country, Is.Not.Null); + Assert.That(country.Cities, Is.EquivalentTo(cities)); + } + + [Test] + public void LoadEntitiesWithExplicitColumnMappings() + { + City[] cities = CreateCities(); + Country country = LoadCountryWithNativeSQL(CreateCountry(cities), "LoadCountryCitiesWithCustomAliases"); + Assert.That(country, Is.Not.Null); + Assert.That(country.Cities, Is.EquivalentTo(cities)); + } + + [Test, ExpectedException(typeof (QueryException))] + public void NativeQueryWithUnresolvedHbmAliasInjection() + { + IDictionary<int, AreaStatistics> stats = CreateStatistics(); + LoadCountryWithNativeSQL(CreateCountry(stats), "LoadAreaStatisticsWithFaultyHbmAliasInjection"); + } + + private Country LoadCountryWithNativeSQL(Country country, string queryName) + { + // Ensure country is saved and session cache is empty to force from now on the reload of all + // persistence objects from the database. + using (ISession session = OpenSession()) + { + using (ITransaction tx = session.BeginTransaction()) + { + session.Save(country); + tx.Commit(); + } + } + using (ISession session = OpenSession()) + { + return session.GetNamedQuery(queryName).SetString("country_code", country.Code).UniqueResult<Country>(); + } + } + + #endregion + + #region Tests - <load-collection> + + [Test] + public void LoadElementCollectionWithCustomLoader() + { + string[] routes = CreateRoutes(); + Country country = CreateCountry(routes); + Country c = SaveAndReload(country); + Assert.That(c, Is.Not.Null, "country"); + Assert.That(c.Routes, Is.EquivalentTo(routes), "country.Routes"); + + } + + [Test] + public void LoadCompositeElementCollectionWithCustomLoader() + { + IDictionary<int, AreaStatistics> stats = CreateStatistics(); + Country country = CreateCountry(stats); + Area a = SaveAndReload(country); + Assert.That(a, Is.Not.Null, "area"); + Assert.That((ICollection)a.Statistics.Keys, Is.EquivalentTo((ICollection)stats.Keys), "area.Keys"); + Assert.That((ICollection)a.Statistics.Values, Is.EquivalentTo((ICollection)stats.Values), "area.Elements"); + } + + [Test] + public void LoadEntityCollectionWithCustomLoader() + { + City[] cities = CreateCities(); + Country country = CreateCountry(cities); + Country c = SaveAndReload(country); + Assert.That(c, Is.Not.Null, "country"); + Assert.That(c.Cities, Is.EquivalentTo(cities), "country.Cities"); + } + + private TArea SaveAndReload<TArea>(TArea area) where TArea : Area + { + //Ensure country is saved and session cache is empty to force from now on the reload of all + //persistence objects from the database. + using (ISession session = OpenSession()) + { + using (ITransaction tx = session.BeginTransaction()) + { + session.Save(area); + tx.Commit(); + } + + } + using (ISession session = OpenSession()) + { + return session.Get<TArea>(area.Code); + } + } + + #endregion + + #region Tests - corner cases to verify backwards compatibility of NH-1612 patch + + [Test] + public void NativeUpdateQueryWithoutResults() + { + using (ISession session = OpenSession()) + { + using (ITransaction tx = session.BeginTransaction()) + { + session.GetNamedQuery("UpdateQueryWithoutResults").ExecuteUpdate(); + tx.Commit(); + } + } + } + + [Test] + public void NativeScalarQueryWithoutResults() + { + using (ISession session = OpenSession()) + { + using (ITransaction tx = session.BeginTransaction()) + { + // Native SQL Query outcome is not validated against <return-*> + // resultset declarations. + session.GetNamedQuery("ScalarQueryWithDefinedResultsetButNoResults").ExecuteUpdate(); + tx.Commit(); + } + } + } + + [Test] + public void NativeScalarQueryWithUndefinedResultset() + { + using (ISession session = OpenSession()) + { + using (session.BeginTransaction()) + { + // Native SQL Query outcome is not validated against <return-*> + // resultset declarations. + var result = session.GetNamedQuery("ScalarQueryWithUndefinedResultset").UniqueResult<int>(); + Assert.That(result, Is.EqualTo(1)); + } + } + } + + [Test] + public void NativeScalarQueryWithDefinedResultset() + { + using (ISession session = OpenSession()) + { + using (session.BeginTransaction()) + { + // Native SQL Query outcome is not validated against <return-*> + // resultset declarations. + var result = session.GetNamedQuery("ScalarQueryWithDefinedResultset").UniqueResult<int>(); + Assert.That(result, Is.EqualTo(2)); + } + } + } + + #endregion + + #region Factory methods + + private static Country CreateCountry() + { + const string COUNTRY_CODE = "WL"; + const string COUNTRY_NAME = "Wonderland"; + return new Country(COUNTRY_CODE, COUNTRY_NAME); + } + + private static Country CreateCountry(params string[] routes) + { + Country country = CreateCountry(); + foreach (var route in routes) + { + country.Routes.Add(route); + } + return country; + } + + private static Country CreateCountry(params City[] cities) + { + Country country = CreateCountry(); + foreach (var city in cities) + { + city.SetParent(country); + } + return country; + } + + private static Country CreateCountry(IDictionary<int, AreaStatistics> statistics) + { + Country country = CreateCountry(); + foreach (var pair in statistics) + { + country.Statistics.Add(pair); + } + return country; + } + + private static string[] CreateRoutes() + { + return new[] {"Yellow Road", "Muddy Path"}; + } + + private static City[] CreateCities() + { + return new[] {new City("EMR", "Emerald City"), new City("GLD", "Golden Town"), new City("NTH", "North End")}; + } + + private static IDictionary<int, AreaStatistics> CreateStatistics() + { + var archimedes = new Person("Archimedes"); + var archibald = new Person("Archibald"); + var amy = new Person("Amy"); + return new Dictionary<int, AreaStatistics> + { + { + 1850, + new AreaStatistics {CitizenCount = 10000, GDP = new MonetaryValue("USD", 20000), Reporter = archimedes} + }, + { + 1900, + new AreaStatistics {CitizenCount = 20000, GDP = new MonetaryValue("USD", 50000), Reporter = archibald} + }, + {1950, new AreaStatistics {CitizenCount = 40000, GDP = new MonetaryValue("USD", 125000)}}, + {2000, new AreaStatistics {CitizenCount = 80000, GDP = new MonetaryValue("USD", 500000), Reporter = amy}}, + }; + } + + #endregion + } +} \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1612/Person.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1612/Person.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1612/Person.cs 2009-01-02 14:37:21 UTC (rev 3969) @@ -0,0 +1,52 @@ +using System; + +namespace NHibernate.Test.NHSpecificTest.NH1612 +{ + public class Person + { + public virtual Guid PersonId { get; private set; } + public virtual string Name { get; private set; } + public virtual int Version { get; private set; } + + protected Person() {} + + public Person(string name) + { + PersonId = Guid.NewGuid(); + Name = name; + } + + public static bool operator ==(Person left, Person right) + { + if (ReferenceEquals(left, right)) + { + return true; + } + if (ReferenceEquals(left, null) || ReferenceEquals(right, null)) + { + return true; + } + return left.PersonId == right.PersonId; + } + + public static bool operator !=(Person left, Person right) + { + return !(left == right); + } + + public override bool Equals(object obj) + { + return this == (Person) obj; + } + + public override int GetHashCode() + { + return PersonId.GetHashCode(); + } + + public override string ToString() + { + return Name; + } + } +} \ No newline at end of file Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2008-12-30 19:41:26 UTC (rev 3968) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2009-01-02 14:37:21 UTC (rev 3969) @@ -558,6 +558,13 @@ <Compile Include="NHSpecificTest\NH1594\A.cs" /> <Compile Include="NHSpecificTest\NH1594\Fixture.cs" /> <Compile Include="NHSpecificTest\NH1608\Fixture.cs" /> + <Compile Include="NHSpecificTest\NH1612\Area.cs" /> + <Compile Include="NHSpecificTest\NH1612\AreaStatistics.cs" /> + <Compile Include="NHSpecificTest\NH1612\City.cs" /> + <Compile Include="NHSpecificTest\NH1612\Country.cs" /> + <Compile Include="NHSpecificTest\NH1612\MonetaryValue.cs" /> + <Compile Include="NHSpecificTest\NH1612\NativeSqlCollectionLoaderFixture.cs" /> + <Compile Include="NHSpecificTest\NH1612\Person.cs" /> <Compile Include="NHSpecificTest\NH1621\Fixture.cs" /> <Compile Include="NHSpecificTest\NH1621\Model.cs" /> <Compile Include="NHSpecificTest\NH280\Fixture.cs" /> @@ -1581,6 +1588,7 @@ <EmbeddedResource Include="Cascade\JobBatch.hbm.xml" /> <EmbeddedResource Include="Deletetransient\Person.hbm.xml" /> <Content Include="DynamicEntity\package.html" /> + <EmbeddedResource Include="NHSpecificTest\NH1612\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH1549\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH1521\AclassWithSpecific.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH1521\AclassWithNothing.hbm.xml" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |