From: <te...@us...> - 2009-03-02 19:46:46
|
Revision: 4104 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=4104&view=rev Author: tehlike Date: 2009-03-02 19:46:38 +0000 (Mon, 02 Mar 2009) Log Message: ----------- Fixing a bug with one-to-many subclass. Fix for NH-1391 Some simplicifactions using automatic properties. Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Loader/AbstractEntityJoinWalker.cs trunk/nhibernate/src/NHibernate/Loader/Collection/BasicCollectionJoinWalker.cs trunk/nhibernate/src/NHibernate/Loader/Collection/OneToManyJoinWalker.cs trunk/nhibernate/src/NHibernate/Loader/JoinWalker.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1391/ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1391/Company.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1391/Fixture.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1391/Mappings.hbm.xml trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1391/Product.cs Modified: trunk/nhibernate/src/NHibernate/Loader/AbstractEntityJoinWalker.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/AbstractEntityJoinWalker.cs 2009-03-01 23:14:40 UTC (rev 4103) +++ trunk/nhibernate/src/NHibernate/Loader/AbstractEntityJoinWalker.cs 2009-03-02 19:46:38 UTC (rev 4104) @@ -44,7 +44,7 @@ SqlString orderByString, string groupByString, SqlString havingString, LockMode lockMode) { WalkEntityTree(persister, Alias); - Persisters = new ILoadable[0]; + this.Persisters = new ILoadable[0]; InitStatementString(projectionString, whereString, orderByString, groupByString, havingString, lockMode); } @@ -57,12 +57,12 @@ SqlString orderBy,string groupBy, SqlString having, LockMode lockMode) { int joins = CountEntityPersisters(associations); - Suffixes = BasicLoader.GenerateSuffixes(joins + 1); + this.Suffixes = BasicLoader.GenerateSuffixes(joins + 1); JoinFragment ojf = MergeOuterJoins(associations); SqlString selectClause = projection ?? - new SqlString(persister.SelectFragment(alias, Suffixes[joins]) + SelectString(associations)); + new SqlString(persister.SelectFragment(alias, this.Suffixes[joins]) + SelectString(associations)); SqlSelectBuilder select = new SqlSelectBuilder(Factory) .SetLockMode(lockMode) Modified: trunk/nhibernate/src/NHibernate/Loader/Collection/BasicCollectionJoinWalker.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Collection/BasicCollectionJoinWalker.cs 2009-03-01 23:14:40 UTC (rev 4103) +++ trunk/nhibernate/src/NHibernate/Loader/Collection/BasicCollectionJoinWalker.cs 2009-03-02 19:46:38 UTC (rev 4104) @@ -40,8 +40,8 @@ { int joins = CountEntityPersisters(associations); int collectionJoins = CountCollectionPersisters(associations) + 1; - Suffixes = BasicLoader.GenerateSuffixes(joins); - CollectionSuffixes = BasicLoader.GenerateSuffixes(joins, collectionJoins); + this.Suffixes = BasicLoader.GenerateSuffixes(joins); + this.CollectionSuffixes = BasicLoader.GenerateSuffixes(joins, collectionJoins); SqlStringBuilder whereString = WhereString(alias, collectionPersister.KeyColumnNames, subquery, batchSize); @@ -72,7 +72,7 @@ SqlSelectBuilder select = new SqlSelectBuilder(Factory) - .SetSelectClause(collectionPersister.SelectFragment(alias, CollectionSuffixes[0]) + .SetSelectClause(collectionPersister.SelectFragment(alias, this.CollectionSuffixes[0]) + SelectString(associations)) .SetFromClause(collectionPersister.TableName, alias) .SetWhereClause(whereString.ToSqlString()) Modified: trunk/nhibernate/src/NHibernate/Loader/Collection/OneToManyJoinWalker.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/Collection/OneToManyJoinWalker.cs 2009-03-01 23:14:40 UTC (rev 4103) +++ trunk/nhibernate/src/NHibernate/Loader/Collection/OneToManyJoinWalker.cs 2009-03-02 19:46:38 UTC (rev 4104) @@ -45,26 +45,29 @@ private void InitStatementString(IOuterJoinLoadable elementPersister, string alias, int batchSize, SqlString subquery) { int joins = CountEntityPersisters(associations); - Suffixes = BasicLoader.GenerateSuffixes(joins + 1); + this.Suffixes = BasicLoader.GenerateSuffixes(joins + 1); int collectionJoins = CountCollectionPersisters(associations) + 1; - CollectionSuffixes = BasicLoader.GenerateSuffixes(joins + 1, collectionJoins); + this.CollectionSuffixes = BasicLoader.GenerateSuffixes(joins + 1, collectionJoins); SqlStringBuilder whereString = WhereString(alias, oneToManyPersister.KeyColumnNames, subquery, batchSize); + string filter = oneToManyPersister.FilterFragment(alias, EnabledFilters); whereString.Insert(0, StringHelper.MoveAndToBeginning(filter)); - + whereString.Add(elementPersister.FilterFragment(alias, new CollectionHelper.EmptyMapClass<string, IFilter>())); JoinFragment ojf = MergeOuterJoins(associations); SqlSelectBuilder select = - new SqlSelectBuilder(Factory).SetSelectClause( - oneToManyPersister.SelectFragment(null, null, alias, Suffixes[joins], CollectionSuffixes[0], true) - + SelectString(associations)).SetFromClause(elementPersister.FromTableFragment(alias) - + elementPersister.FromJoinFragment(alias, true, true)).SetWhereClause( - whereString.ToSqlString()).SetOuterJoins(ojf.ToFromFragmentString, - ojf.ToWhereFragmentString - + elementPersister.WhereJoinFragment(alias, true, true)); + new SqlSelectBuilder(Factory) + .SetSelectClause( + oneToManyPersister.SelectFragment(null, null, alias, this.Suffixes[joins], this.CollectionSuffixes[0], true) + + SelectString(associations)) + .SetFromClause(elementPersister.FromTableFragment(alias) + + elementPersister.FromJoinFragment(alias, true, true)) + .SetWhereClause(whereString.ToSqlString()) + .SetOuterJoins(ojf.ToFromFragmentString, + ojf.ToWhereFragmentString + elementPersister.WhereJoinFragment(alias, true, true)) + .SetOrderByClause(OrderBy(associations, oneToManyPersister.GetSQLOrderByString(alias))); - select.SetOrderByClause(OrderBy(associations, oneToManyPersister.GetSQLOrderByString(alias))); if (Factory.Settings.IsCommentsEnabled) { Modified: trunk/nhibernate/src/NHibernate/Loader/JoinWalker.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Loader/JoinWalker.cs 2009-03-01 23:14:40 UTC (rev 4103) +++ trunk/nhibernate/src/NHibernate/Loader/JoinWalker.cs 2009-03-02 19:46:38 UTC (rev 4104) @@ -19,77 +19,26 @@ private readonly ISet<AssociationKey> visitedAssociationKeys = new HashedSet<AssociationKey>(); private readonly IDictionary<string, IFilter> enabledFilters; - private string[] suffixes; - private string[] collectionSuffixes; - private ILoadable[] persisters; - private int[] owners; - private EntityType[] ownerAssociationTypes; - private ICollectionPersister[] collectionPersisters; - private int[] collectionOwners; - private string[] aliases; - private LockMode[] lockModeArray; - private SqlString sql; + public string[] CollectionSuffixes { get; set; } - public string[] CollectionSuffixes - { - get { return collectionSuffixes; } - set { collectionSuffixes = value; } - } + public LockMode[] LockModeArray { get; set; } - public LockMode[] LockModeArray - { - get { return lockModeArray; } - set { lockModeArray = value; } - } + public string[] Suffixes { get; set; } - public string[] Suffixes - { - get { return suffixes; } - set { suffixes = value; } - } + public string[] Aliases { get; set; } - public string[] Aliases - { - get { return aliases; } - set { aliases = value; } - } + public int[] CollectionOwners { get; set; } - public int[] CollectionOwners - { - get { return collectionOwners; } - set { collectionOwners = value; } - } + public ICollectionPersister[] CollectionPersisters { get; set; } - public ICollectionPersister[] CollectionPersisters - { - get { return collectionPersisters; } - set { collectionPersisters = value; } - } + public EntityType[] OwnerAssociationTypes { get; set; } - public EntityType[] OwnerAssociationTypes - { - get { return ownerAssociationTypes; } - set { ownerAssociationTypes = value; } - } + public int[] Owners { get; set; } - public int[] Owners - { - get { return owners; } - set { owners = value; } - } + public ILoadable[] Persisters { get; set; } - public ILoadable[] Persisters - { - get { return persisters; } - set { persisters = value; } - } + public SqlString SqlString { get; set; } - public SqlString SqlString - { - get { return sql; } - set { sql = value; } - } - protected ISessionFactoryImplementor Factory { get { return factory; } @@ -708,15 +657,15 @@ int joins = CountEntityPersisters(associations); int collections = CountCollectionPersisters(associations); - collectionOwners = collections == 0 ? null : new int[collections]; - collectionPersisters = collections == 0 ? null : new ICollectionPersister[collections]; - collectionSuffixes = BasicLoader.GenerateSuffixes(joins + 1, collections); + this.CollectionOwners = collections == 0 ? null : new int[collections]; + this.CollectionPersisters = collections == 0 ? null : new ICollectionPersister[collections]; + this.CollectionSuffixes = BasicLoader.GenerateSuffixes(joins + 1, collections); - persisters = new ILoadable[joins]; - aliases = new String[joins]; - owners = new int[joins]; - ownerAssociationTypes = new EntityType[joins]; - lockModeArray = ArrayHelper.FillArray(lockMode, joins); + this.Persisters = new ILoadable[joins]; + this.Aliases = new String[joins]; + this.Owners = new int[joins]; + this.OwnerAssociationTypes = new EntityType[joins]; + this.LockModeArray = ArrayHelper.FillArray(lockMode, joins); int i = 0; int j = 0; @@ -725,10 +674,10 @@ { if (!oj.IsCollection) { - persisters[i] = (ILoadable)oj.Joinable; - aliases[i] = oj.RHSAlias; - owners[i] = oj.GetOwner(associations); - ownerAssociationTypes[i] = (EntityType)oj.JoinableType; + this.Persisters[i] = (ILoadable)oj.Joinable; + this.Aliases[i] = oj.RHSAlias; + this.Owners[i] = oj.GetOwner(associations); + this.OwnerAssociationTypes[i] = (EntityType)oj.JoinableType; i++; } else @@ -738,25 +687,25 @@ if (oj.JoinType == JoinType.LeftOuterJoin) { //it must be a collection fetch - collectionPersisters[j] = collPersister; - collectionOwners[j] = oj.GetOwner(associations); + this.CollectionPersisters[j] = collPersister; + this.CollectionOwners[j] = oj.GetOwner(associations); j++; } if (collPersister.IsOneToMany) { - persisters[i] = (ILoadable)collPersister.ElementPersister; - aliases[i] = oj.RHSAlias; + this.Persisters[i] = (ILoadable)collPersister.ElementPersister; + this.Aliases[i] = oj.RHSAlias; i++; } } } - if (ArrayHelper.IsAllNegative(owners)) - owners = null; + if (ArrayHelper.IsAllNegative(this.Owners)) + this.Owners = null; - if (collectionOwners != null && ArrayHelper.IsAllNegative(collectionOwners)) - collectionOwners = null; + if (this.CollectionOwners != null && ArrayHelper.IsAllNegative(this.CollectionOwners)) + this.CollectionOwners = null; } /// <summary> @@ -782,11 +731,11 @@ OuterJoinableAssociation next = (i == associations.Count - 1) ? null : associations[i + 1]; IJoinable joinable = join.Joinable; - string entitySuffix = (suffixes == null || entityAliasCount >= suffixes.Length) ? null : suffixes[entityAliasCount]; + string entitySuffix = (this.Suffixes == null || entityAliasCount >= this.Suffixes.Length) ? null : this.Suffixes[entityAliasCount]; - string collectionSuffix = (collectionSuffixes == null || collectionAliasCount >= collectionSuffixes.Length) + string collectionSuffix = (this.CollectionSuffixes == null || collectionAliasCount >= this.CollectionSuffixes.Length) ? null - : collectionSuffixes[collectionAliasCount]; + : this.CollectionSuffixes[collectionAliasCount]; string selectFragment = joinable.SelectFragment(next == null ? null : next.Joinable, next == null ? null : next.RHSAlias, join.RHSAlias, Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1391/Company.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1391/Company.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1391/Company.cs 2009-03-02 19:46:38 UTC (rev 4104) @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NHibernate.Test.NHSpecificTest.NH1391 +{ + public class Company + { + public virtual int Id { get; set; } + public virtual IList<ProductA> Products { get; set; } + } +} Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1391/Fixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1391/Fixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1391/Fixture.cs 2009-03-02 19:46:38 UTC (rev 4104) @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Text; +using NUnit.Framework; +using NUnit.Framework.SyntaxHelpers; +namespace NHibernate.Test.NHSpecificTest.NH1391 +{ + [TestFixture] + public class Fixture:BugTestCase + { + protected override void OnSetUp() + { + using(var session=OpenSession()) + using(var tran=session.BeginTransaction()) + { + var producta = new ProductA {Name = "producta"}; + var productb = new ProductB {Name = "productb"}; + var company = new Company { Products = new List<ProductA>() }; + company.Products.Add(producta); + producta.Company = company; + productb.Company = company; + session.Save(company); + session.Save(productb); + session.Save(producta); + tran.Commit(); + } + } + protected override void OnTearDown() + { + using (var session = OpenSession()) + using (var tran = session.BeginTransaction()) + { + session.Delete("from Product"); + session.Delete("from Company"); + tran.Commit(); + } + } + + + [Test] + public void Can_discriminate_subclass_on_list_with_lazy_loading() + { + using (var session = OpenSession()) + using (var tran = session.BeginTransaction()) + { + var company = session.Get<Company>(1); + Assert.That(company, Is.Not.Null); + Assert.That(company.Products, Has.Count(1)); + Assert.That(company.Products[0], Is.AssignableFrom(typeof (ProductA))); + tran.Commit(); + } + } + } +} Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1391/Mappings.hbm.xml =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1391/Mappings.hbm.xml (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1391/Mappings.hbm.xml 2009-03-02 19:46:38 UTC (rev 4104) @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8" ?> +<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" + assembly="NHibernate.Test" + namespace="NHibernate.Test.NHSpecificTest.NH1391"> + + <class name="Product" discriminator-value="0"> + <id name="Id" type="int"> + <generator class="native"/> + </id> + <discriminator column="ProdType" type="int"/> + <property name="Name" type="string"/> + <many-to-one name="Company" column="CompanyId" not-null="true"/> + <subclass name="ProductA" discriminator-value="10"/> + <subclass name="ProductB" discriminator-value="20"/> + </class> + <class name="Company"> + <id name="Id"> + <generator class="native"/> + </id> + <bag name="Products" lazy="true" + inverse="true"> + <key column="CompanyId" /> + <one-to-many class="ProductA"/> + </bag> + </class> +</hibernate-mapping> \ No newline at end of file Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1391/Product.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1391/Product.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1391/Product.cs 2009-03-02 19:46:38 UTC (rev 4104) @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NHibernate.Test.NHSpecificTest.NH1391 +{ + public class Product + { + public virtual int Id { get; set; } + public virtual string Name { get; set; } + public virtual Company Company { get; set; } + } + public class ProductA:Product + { + + } + public class ProductB:Product + { + + } +} Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2009-03-01 23:14:40 UTC (rev 4103) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2009-03-02 19:46:38 UTC (rev 4104) @@ -416,6 +416,9 @@ <Compile Include="NHSpecificTest\NH1289\PurchaseItem.cs" /> <Compile Include="NHSpecificTest\NH1289\PurchaseOrder.cs" /> <Compile Include="NHSpecificTest\NH1289\WorkflowItem.cs" /> + <Compile Include="NHSpecificTest\NH1391\Company.cs" /> + <Compile Include="NHSpecificTest\NH1391\Fixture.cs" /> + <Compile Include="NHSpecificTest\NH1391\Product.cs" /> <Compile Include="NHSpecificTest\NH1665\Fixture.cs" /> <Compile Include="NHSpecificTest\NH1665\MyEntity.cs" /> <Compile Include="NHSpecificTest\NH1443\Fixture.cs" /> @@ -1670,6 +1673,7 @@ <EmbeddedResource Include="Cascade\JobBatch.hbm.xml" /> <EmbeddedResource Include="Deletetransient\Person.hbm.xml" /> <Content Include="DynamicEntity\package.html" /> + <EmbeddedResource Include="NHSpecificTest\NH1391\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH1691\Mappings.hbm.xml" /> <EmbeddedResource Include="NHSpecificTest\NH1689\Mappings.hbm.xml" /> <EmbeddedResource Include="VersionTest\Db\MsSQL\SimpleVersioned.hbm.xml" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |