Try fast search NHibernate

03 October 2009

How you shouldn’t write your mapping

More than one time, in my courses, in this blog and in various NH’s users list, I talked about a rule of thumb about mappings: not try to be clear because it obscures.

Have a look to this mapping:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<
class name="YourApp.Common.DataObjects.Address, YourApp"
table="Address">
<
id name="Id" type="Int32" unsaved-value="null">
<
column name="Id"
length="4" sql-type="int"
not-null="true" unique="true" index="PK_Address"/>
<
generator class="native" />
</
id>
<
property name="Address1" type="String">
<
column name="Address1" length="255"
sql-type="varchar" not-null="true"/>
</
property>
<
property name="Address2" type="String">
<
column name="Address2" length="255"
sql-type="varchar" not-null="false"/>
</
property>
<
property name="City" type="String">
<
column name="City" length="255"
sql-type="varchar" not-null="true"/>
</
property>
<
property name="State" type="String">
<
column name="`State`" length="2"
sql-type="varchar" not-null="true"/>
</
property>
<
property name="Zip" type="String">
<
column name="Zip" length="12"
sql-type="varchar" not-null="true"/>
</
property>
<
many-to-one name="Contact" class="YourApp.Common.DataObjects.Contact, YourApp">
<
column name="Contact_Id" length="4"
sql-type="int" not-null="false"/>
</
many-to-one>
<
bag name="BillToOrderHeaders" inverse="true" lazy="true" cascade="all-delete-orphan">
<
key column="BillToAddress_Id"/>
<
one-to-many
class="YourApp.Common.DataObjects.OrderHeader, YourApp"/>
</
bag>
<
bag name="ShipToOrderHeaders" inverse="true" lazy="true" cascade="all-delete-orphan">
<
key column="ShipToAddress_Id"/>
<
one-to-many
class="YourApp.Common.DataObjects.OrderHeader, YourApp"/>
</
bag>
</
class>
</
hibernate-mapping>

This is how it may look having the same result:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="YourApp"
namespace="YourApp.Common.DataObjects">

<
class name="Address">
<
id name="Id">
<
generator class="native" />
</
id>
<
property name="Address1" not-null="true" />
<
property name="Address2"/>
<
property name="City" not-null="true"/>
<
property name="State" length="2" not-null="true"/>
<
property name="Zip" length="12" not-null="true"/>
<
many-to-one name="Contact" column="Contact_Id"/>
<
bag name="BillToOrderHeaders" inverse="true" cascade="all-delete-orphan">
<
key column="BillToAddress_Id"/>
<
one-to-many class="OrderHeader"/>
</
bag>
<
bag name="ShipToOrderHeaders" inverse="true" cascade="all-delete-orphan">
<
key column="ShipToAddress_Id"/>
<
one-to-many class="OrderHeader"/>
</
bag>
</
class>
</
hibernate-mapping>
In this second representation we can understand immediately which are the difference with the NHibernate convention and, over all, you are not hurting your eyes reading it ;-) .

4 comments:

  1. I've just a two month experience studying NHibernate, and I've always found your notes and suggestions very helpful.

    Yet this time I disagree: when I look at my mapping file, I want to get all possible information about the underlying database, and it's easier (for me) to read them in this file than to remember NH conventions and defaults.

    But... you know, I'm just a NH newbie ;)

    ReplyDelete
  2. Exactly as beginner you should write less as possible in the mapping.
    The mapping is "the language to program NH": less code less bug.

    ReplyDelete
  3. I suppose the developer of the original mapping just wanted to be explicit and be on the safe side if convention is going to change in version Next+N.

    ReplyDelete
  4. Absolutely 100% yes!

    I'd like to add this for those of you who use the mapping to tell you the schema of the database:

    A mapping like the first one above only tells you what *should* be in your database. This is not useful information. You should be concerned with what *is* in your database.

    ReplyDelete