Ryan.Bartsch
Ryan.Bartsch

Reputation: 4200

Fluent NHibernate referencing entity with natural key

I'm using Fluent NHibernate automapping functionality. I've managed to get the database mappings pretty close using conventions, but there are a few things for which I need IAutoMappingOverride.

In a legacy system, I have an entity class, 'Campus', that has a NATURAL key, 'Code'. The Oracle database type of this key is VARCHAR2(3 BYTE). I'm using an override for this, as my conventions would otherwise assume an autogenerated surrogate key. I have other entity classes (e.g. Building) that reference the Campus entity (with its natural key) as shown below

<class name="Campus" table="CAMPUS" ... >
<id name="Id" type="String">
  <column name="camp_code" sql-type="VARCHAR2(3 BYTE)" />
  <generator class="assigned" />
</id>
<set name="Buildings" ...>
  <key foreign-key="buil_camp_fk">
    <column name="camp_code" />
  </key>
  <one-to-many class="Building" />
</set>
...
</class>

<class name="Building" table="BUILDING" ... >
...
<many-to-one class="Campus" name="Campus">
<column name="camp_code" not-null="true" />
</many-to-one>
...
</class>

The HBM mappings that I've generated appear to be correct using the following overrides:

Public Class CampusMappingOverride
Implements IAutoMappingOverride(Of Campus)

Public Sub Override(ByVal mapping As AutoMapping(Of Campus)) Implements IAutoMappingOverride(Of Campus).Override
  mapping.Id(Function(campus) campus.Id, "camp_code").CustomSqlType("VARCHAR2(3 BYTE)")
End Sub

End Class

Public Class BuildingMappingOverride
Implements IAutoMappingOverride(Of Building)

Public Sub Override(ByVal mapping As AutoMapping(Of Building)) Implements IAutoMappingOverride(Of Building).Override
  mapping.References(Of Campus)(Function(building) building.Campus, "camp_code")
End Sub

End Class

However, the schema export (Oracle database) is not correct.

create table BUILDING (
   ...
   camp_code NVARCHAR2(255) not null,
   ...
)
create table CAMPUS (
   camp_code VARCHAR2(3 BYTE) not null,
   ...
   primary key (camp_code)
)

As you can see building.camp_code is NVARCHAR2(255), which seems to be the default for String in Oracle, but it should be VARCHAR2(3 BYTE).

I saw there is a mapping.NaturalId function, but I'm not sure if this is working correctly, because if I use this in place of Id, I get a mapping exception.

I would appreciate any help in how to deal with this scenario.

Kind regards, Ryan.

Upvotes: 1

Views: 541

Answers (1)

J. Ed
J. Ed

Reputation: 6742

I agree with you that FNH should recognize the column type of the other side of the association as being VARCHAR, but apparently it doesn't. It may be worthwhile to ask around at the FNH mailing list

but in order to solve your current problem, I think that in your mapping override of Building, you can specify exactly what type of column to use, (use the Column() function) so you can correct that behaviour by yourself.

Upvotes: 0

Related Questions