I have the following solution project structure:
In the Core project I have an entity Customer defiend. In the XTend project, I have an entity defined that subclasses Customer named xCustomer (for lack of a better name at this time...).
The idea here is that we have a Core domain model in our application. A customer can then create a new assembly that contains extensions to our core model. When the extension assembly is present a smart IRepository class will return a subclass of the core class instead.
I am attempting to map this relationship in NHibernate. Using Fluent NHibernate I was able to generate this mapping:
<?xml version="1.0" encoding="utf-8"?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="false" assembly="NHibernate.Core.Entites" namespace="NHibernate.Entites" default-access="field.camelcase-underscore"> <!-- Customer is located in assembly Application.Core.Entities --> <class name="Customer" table="Customers" xmlns="urn:nhibernate-mapping-2.2"> <id name="Id" column="Id" type="Int64"> <generator class="native" /> </id> <component name="Name" insert="true" update="true"> <property name="LastName" column="LastName" length="255" type="String" not-null="true"> <column name="LastName" /> </property> <property name="FirstName" column="FirstName" length="255" type="String" not-null="true"> <column name="FirstName" /> </property> </component> <!-- xCustomer is located in assembly Application.XTend.CustomerName.Entities --> <joined-subclass name="xCustomer" table="xCustomer"> <key column="CustomerId" /> <property name="CustomerType" column="CustomerType" length="255" type="String" not-null="true"> <column name="CustomerType" /> </property> </joined-subclass> </class> </hibernate-mapping>
But NHib throws the following error:
NHibernate.MappingException: persistent class Application.Entites.xCustomer, Application.Core.Entites not found ---> System.TypeLoadException: Could not load type 'Application.Entites.xCustomer' from assembly 'Application.Core.Entites, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'..
Which makes sense xCustomer is not defined in the Core library. I took my quandary to the NHibernate Users mailing list and StackOverflow. After some helpful suggestions and pointers, I discovered that the solution was so obvious that I am somewhat embarrassed that I couldn't see it.
The hibernate-mapping attributes assembly and namespace are convenient short cuts that allow you to not have to fully qualify your class names. This lets you have the nice mark up , but the name attribute of both class and joined-subclass elements can take a fully qualified assembly name as well.
So the above broken mapping file can be fixed like so:
<joined-subclass name="Application.XTend.CustomerName.Entities.xCustomer, Application.XTend.CustomerName.Entities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="xCustomer"> <key column="CustomerId" /> <property name="CustomerType" column="CustomerType" length="255" type="String" not-null="true"> <column name="CustomerType" /> </property> </joined-subclass>
This works as I expected it to. So I then took a look at the Fluent-NHibernate source and created a patch complete with working unit tests to resolve the issue and submitted it to the project.
So at the end of the day, I learned something about NHibernate and the Fluent-NHibernate team got a patch to resolve and obscure bug.
Steam Community MySpace FaceBook LinkedIn Twitter BrightKite Reading List Source Code Repository