You can use the property-ref
attribute to join to a column other than the primary key.
If you tell one lie...
So, you previously had something like this:
<class name="Person">
<id name="Id"
column="Id"
type="Int32"
generator="native" />
</class>
<class name="Servant">
<id name="Id"
column="Id"
type="Int32"
generator="native" />
<many-to-one name="Person"
column="Person_Id"
not-null="true"
unique="true" />
</class>
<class name="User">
<id name="Id"
column="Id"
type="Int32"
generator="native" />
<many-to-one name="Servant"
column="Servant_Id" />
</class>
Without changing the database schema, you've removed the <class name="Servant">
and replaced it with this:
<class name="Person">
<!-- Rest of Person stays the same, except we insert this: -->
<joined-subclass name="Servant">
<key column="Person_Id" />
</joined-subclass>
</class>
Even though Person_Id
is not really the primary key for the Servant
table, we've told NHibernate to pretend that it is - which will still work fine, as long as that column is not null
and unique
. The problem you're running into now is that NHibernate wants to join on User.Servant_Id = Servant.Person_Id
, because it thinks that Person_Id
is the primary key of the Servant
table.
So, how do we fix it? How do we get NHibernate to still join on User.Servant_Id = Servant.Id
?
Easy. We simply lie to NHibernate again, and tell it that the User.Servant
property shouldn't join to Servant
's primary key, but to a different unique column on that table, Id
(which actually is the primary key, but shhh, don't tell NHibernate).
First, we need to add Servant
's id as a property. We'll name it ServantId
so as to not shadow the Id
property we inherit from Person
. We'll also set insert
, update
, and generated
appropriately to ensure NHibernate allows the database to generate this value.
<joined-subclass name="Servant">
<key column="Person_Id" />
<property name="ServantId"
column="Id"
insert="false"
update="false"
generated="insert" />
</class>
Next, we modify the mapping for User
's Servant
property, telling it to join to that new property in the other table instead of the primary key.
<many-to-one name="Servant"
column="Servant_Id"
property-ref="ServantId" />
Viola! The above description should be enough information to paint all sides of the picture (DB Tables, NH Mappings, C# Classes), but if it's not, let me know and I can be more explicit.