My favorites | Sign in
Project Logo
       
New issue | Search
for
| Advanced search | Search tips
Issue 127: Bug: Fluent is producing both joined-subclass and subclass for each child entity
7 people starred this issue and may be notified of changes. Back to list
Status:  Accepted
Owner:  ----
Type-Defect
Priority-High


Sign in to add a comment
 
Reported by andrew.awaijane, Feb 23, 2009
What steps will reproduce the problem?

In this example I have a Parent class Customer with child classes 
AutomotiveCustomer and RealEstateCustomer. The child classes do NOT have 
coresponding tables in the databse so I do not intend for them to be 
joined-subclasses (they inherit from customer and do not have any unique 
fields). They can be identified by a field called CustomerType in the 
Customer table. See the section ".ForTypesThatDeriveFrom<>" below where I 
have specified discriminater column and values. 

sessionFactory = Fluently.Configure()
	.Database(MsSqlConfiguration
				  .MsSql2005
				  .ConnectionString(
				  c => c.Is("Data Source=(local);Initial 
Catalog=Unity3;Integrated Security=True"))
				  .ShowSql())
	.Mappings(m =>
		m.AutoMappings
			.Add
(AutoPersistenceModel.MapEntitiesFromAssemblyOf<BusinessEntity>()
				.Where(type => type.Namespace.EndsWith
("Unity3.Logic.Entities") &&
					type.Name != "Customer")
				.ForTypesThatDeriveFrom<Customer>(
					c => 
c.DiscriminateSubClassesOnColumn("CustomerType", 1000)
					
	.SubClass<AutomotiveCustomer>(1001, s => s.Map(ac => 
ac.CustomerType))
					
	.SubClass<RealEstateCustomer>(2001, s => s.Map(ac => 
ac.CustomerType)))
				.WithConvention(convention =>
				{
					convention.IsBaseType =
						type => type == typeof
(BusinessEntity);  

					convention.GetTableName = type =>
						"Core." + 
Inflector.Pluralize(type.Name);

					convention.GetForeignKeyName = 
type =>
						(type.Name.EndsWith
("edBy") ||
						type.Name.EndsWith("Type") 
||
						type.Name.EndsWith("Code"))
						? type.Name
						: type.Name + "Id";

				
	convention.GetForeignKeyNameOfParent =
						type => (type.Name.Equals
("BusinessEntity"))
						? "Id"
						: type.Name + "Id";

					convention.DefaultLazyLoad = false;
				}))
				.ExportTo(@"F:\Test\FluentNHibernate\"))
	.BuildSessionFactory();

What is the expected output? What do you see instead?

I expect to have a subclass for each of the child types AutomotiveCustomer 
and RealEstateCustomer.
Instead I am seeing from the NHibernate xml output that both a joined-
subclass and a subclass are being created for each of the child types. 
NHibernate does not support both a joined-subclass and a subclass refering 
to the same entity:
The element 'class' in namespace 'urn:nhibernate-mapping-2.2' has invalid 
child element 'subclass' in namespace 'urn:nhibernate-mapping-2.2'.

Here is the Nhibernate xml output:

<?xml version="1.0" encoding="utf-8"?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="false" 
assembly="UnityWorks.Unity3.Logic" 
namespace="UnityWorks.Unity3.Logic.Entities">
  <class name="Customer" table="Core.Customers" xmlns="urn:nhibernate-
mapping-2.2" discriminator-value="1000">
    <id name="Id" column="Id" type="Int64">
      <generator class="identity" />
    </id>
    <discriminator column="CustomerType" type="Int32" />
    <property name="ProductionPriority" type="Byte">
      <column name="ProductionPriority" />
    </property>
    <property name="Status" 
type="FluentNHibernate.Mapping.GenericEnumMapper`1
[[UnityWorks.Unity3.Logic.BusinessEntityStatus, UnityWorks.Unity3.Logic, 
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], FluentNHibernate, 
Version=0.1.0.0, Culture=neutral, PublicKeyToken=8aa435e3cb308880">
      <column name="Status" />
    </property>
    <property name="Name" length="100" type="String">
      <column name="Name" />
    </property>
    <property name="CustomerType" type="Int32">
      <column name="CustomerType" />
    </property>
    <bag name="History">
      <key column="CustomerId" />
      <one-to-many 
class="UnityWorks.Unity3.Logic.Entities.BusinessEntityAudit, 
UnityWorks.Unity3.Logic, Version=1.0.0.0, Culture=neutral, 
PublicKeyToken=null" />
    </bag>
    <bag name="Libraries">
      <key column="CustomerId" />
      <one-to-many class="UnityWorks.Unity3.Logic.Entities.Library, 
UnityWorks.Unity3.Logic, Version=1.0.0.0, Culture=neutral, 
PublicKeyToken=null" />
    </bag>
    <joined-subclass 
name="UnityWorks.Unity3.Logic.Entities.AutomotiveCustomer, 
UnityWorks.Unity3.Logic, Version=1.0.0.0, Culture=neutral, 
PublicKeyToken=null" table="Core.AutomotiveCustomers">
      <key column="CustomerId" />
    </joined-subclass>
    <joined-subclass 
name="UnityWorks.Unity3.Logic.Entities.RealEstateCustomer, 
UnityWorks.Unity3.Logic, Version=1.0.0.0, Culture=neutral, 
PublicKeyToken=null" table="Core.RealEstateCustomers">
      <key column="CustomerId" />
    </joined-subclass>
    <subclass name="UnityWorks.Unity3.Logic.Entities.AutomotiveCustomer, 
UnityWorks.Unity3.Logic, Version=1.0.0.0, Culture=neutral, 
PublicKeyToken=null" discriminator-value="1001">
      <property name="CustomerType" type="Int32">
        <column name="CustomerType" />
      </property>
    </subclass>
    <subclass name="UnityWorks.Unity3.Logic.Entities.RealEstateCustomer, 
UnityWorks.Unity3.Logic, Version=1.0.0.0, Culture=neutral, 
PublicKeyToken=null" discriminator-value="2001">
      <property name="CustomerType" type="Int32">
        <column name="CustomerType" />
      </property>
    </subclass>
  </class>
</hibernate-mapping>


What version of the product are you using? On what operating system?
Revision: 361 

Thanks for looking into this. - Andrew
Comment 1 by jimitndiaye, Mar 05, 2009
I encountered this same issue some time back and submitted a patch for it which has 
not yet been applied.
Comment 2 by raroldan, Apr 15, 2009
This issue should probably be escalated to High as there is no way of using the
automapping funcionality to create an inheritance hierarchy with a discriminator.
Comment 4 by Hudson.Akridge, Apr 25, 2009
(No comment was entered for this change.)
Summary: Bug: Fluent is producing both joined-subclass and subclass for each child entity
Comment 5 by jagregory.com, Jul 19, 2009
Is this still occurring?
Comment 6 by jagregory.com, Jul 28, 2009
Assuming this isn't a problem anymore.
Status: Fixed
Comment 7 by james.freiwirth, Oct 20, 2009
Having a similar issue to this except I'm not even getting the <subclass> elements so
I end up with a discriminator and joined-subclasses. Weird.

Comment 8 by james.freiwirth, Oct 20, 2009
Have attached an example of this problem (tested using latest FNH from SVN trunk). 

Notice how the mapping file generated uses <joined-subclass> instead of <subclass>
despite having a discriminator.
FluentTest.zip
5.1 KB   Download
Comment 9 by paul.batum, Nov 02, 2009
Something really weird is happening with this. I've confirmed that James's example
project does generate a discriminator AND joined-subclass elements.

But I then ported his changes into my own FNH testing solution and no discriminator
was generated. I am yet to determine the cause.. more investigation required.
Status: Accepted
Comment 10 by james.freiwirth, Dec 21, 2009
Any update on this?
Sign in to add a comment

Hosted by Google Code