When using an inverted one-to-many in a "Table per subclass using
discriminator" inheritance hierarchy; nHibernate looks for the many-to-
one back-reference on the table mapped to the base class instead of on
the derived class' table.

In the mapping below Employer.Employees is implemented using a FK on
the Employees table. The generated SQL looks for EmployerId on Person
(employees0_) instead of Employee (employees0_1_).

This is not an issue with a many-to-one implementation as seen in the
Person to Country relationship.

Am I doing something wrong here or is this a "unsupported feature"?

Notes:
- We cannot use joined-subclass on our current system.
- The below mapping, stack trace, etc is an exerpt of an app I wrote
to reproduce the problem. I'll email the code thorugh on request.

NHibernate version:2.0.1.4000

Mapping documents:
<class table="Person" name="JoinedSubclass.Person, JoinedSubclass"
lazy="false" discriminator-value="P">
<id name="Id" column="PersonId" type="Int32" unsaved-value="0">
<generator class="identity" />
</id>
<discriminator column="Discriminator" type="Char"/>
<property name="FirstName"/>
<property name="LastName"/>
<many-to-one name="Country" column="CountryId" cascade="all"
lazy="false" class="JoinedSubclass.Country, JoinedSubclass"/>
<subclass name="JoinedSubclass.Employee, JoinedSubclass" lazy="true"
discriminator-value="E">
<join table="Employee">
<key column="PersonId"/>
<property name="Designation"/>
<many-to-one name="Employer" column="EmployerId" cascade="all"
lazy="false" class="JoinedSubclass.Employer, JoinedSubclass"/>
</join>
</subclass>
</class>

<class table="Employer" name="JoinedSubclass.Employer, JoinedSubclass"
lazy="false" >
<id name="Id" column="EmployerId" type="Int32" unsaved-
value="0"><generator class="identity" /></id>
<set name="Employees" table="Employee" cascade="all" inverse="true"
lazy="false">
<key column="EmployerId"/>
<one-to-many class="JoinedSubclass.Employee, JoinedSubclass"/>
</set>
<property name="Name"/>
</class>


<class table="Country" name="JoinedSubclass.Country, JoinedSubclass"
lazy="false" >
<id name="Id" column="CountryId" type="Int32" unsaved-value="0">
<generator class="identity" />
</id>
<property name="Name"/>
</class>

Code between sessionFactory.openSession() and session.close():
currentSession.Load<Employer>(38);

Full stack trace of any exception that occurs:
at NHibernate.Loader.Loader.LoadCollection(ISessionImplementor
session, Object id, IType type)
at NHibernate.Loader.Collection.CollectionLoader.Initialize(Object id,
ISessionImplementor session)
at
NHibernate.Persister.Collection.AbstractCollectionPersister.Initialize
(Object key, ISessionImplementor session)
at
NHibernate.Event.Default.DefaultInitializeCollectionEventListener.OnInitializeCollection
(InitializeCollectionEvent event)
at NHibernate.Impl.SessionImpl.InitializeCollection
(IPersistentCollection collection, Boolean writing)
at
NHibernate.Collection.AbstractPersistentCollection.ForceInitialization
()
at
NHibernate.Engine.StatefulPersistenceContext.InitializeNonLazyCollections
()
at NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections
(ISessionImplementor session, QueryParameters queryParameters, Boolean
returnProxies)
at NHibernate.Loader.Loader.LoadEntity(ISessionImplementor session,
Object id, IType identifierType, Object optionalObject, String
optionalEntityName, Object optionalIdentifier, IEntityPersister
persister)
at NHibernate.Loader.Entity.AbstractEntityLoader.Load
(ISessionImplementor session, Object id, Object optionalObject, Object
optionalId)
at NHibernate.Loader.Entity.AbstractEntityLoader.Load(Object id,
Object optionalObject, ISessionImplementor session)
at NHibernate.Persister.Entity.AbstractEntityPersister.Load(Object id,
Object optionalObject, LockMode lockMode, ISessionImplementor
session)
at NHibernate.Event.Default.DefaultLoadEventListener.LoadFromDatasource
(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad,
LoadType options)
at NHibernate.Event.Default.DefaultLoadEventListener.DoLoad(LoadEvent
event, IEntityPersister persister, EntityKey keyToLoad, LoadType
options)
at NHibernate.Event.Default.DefaultLoadEventListener.Load(LoadEvent
event, IEntityPersister persister, EntityKey keyToLoad, LoadType
options)
at NHibernate.Event.Default.DefaultLoadEventListener.ProxyOrLoad
(LoadEvent event, IEntityPersister persister, EntityKey keyToLoad,
LoadType options)
at NHibernate.Event.Default.DefaultLoadEventListener.OnLoad(LoadEvent
event, LoadType loadType)
at NHibernate.Impl.SessionImpl.FireLoad(LoadEvent event, LoadType
loadType)
at NHibernate.Impl.SessionImpl.Load(Type clazz, Object id)
at JoinedSubclass.NHibernateHelper.SaveOrUpdate(IDomainClass
inObject)

Name and version of the database you are using:
SQL Server 2005

The generated SQL (show_sql=true):
exec sp_executesql N'SELECT employees0_.EmployerId as EmployerId3_,
employees0_.PersonId as PersonId3_, employees0_.PersonId as
PersonId0_2_, employees0_.FirstName as
FirstName0_2_, employees0_.LastName as LastName0_2_,
employees0_.CountryId as CountryId0_2_, employees0_1_.Designation as
Designat2_1_2_, employees0_1_.EmployerId as
EmployerId1_2_, country1_.CountryId as CountryId3_0_, country1_.Name
as Name3_0_, employer2_.EmployerId as EmployerId2_1_, employer2_.Name
as Name2_1_ FROM Person employees0_
inner join Employee employees0_1_ on
employees0_.PersonId=employees0_1_.PersonId left outer join Country
country1_ on employees0_.CountryId=country1_.CountryId left outer
join
Employer employer2_ on employees0_1_.EmployerId=employer2_.EmployerId
WHERE employees0_.employer...@p0',N'@p0 int',@p0=37

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/nhusers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to