One of the things that is not very obvious when using NHibernate is how to using Enumerations. If you merely map an enum with the hbm.xml, NHibernate will persist that class member as an int, which is the underlying type of an Enum value type. Even if you have your database table configured with a string field, you’ll get an integer in your string field.
To have NHibernate use the string representation of the enum for storing in the database, you need to use a special type class. Below is a simple example of using the EnumStringType that NHibernate provides. Consider the following enum that I want to use in my class (this is a very simplified example):
public enum DeliveryStatus
{
Pending,
Ready,
Sent
}
When mapping this in my class, NHibernate would persist 0, 1, and 2 in my database. What I actually want are the strings to be stored in my table (no comments about normalization, please). Here is a wierd thing you have to do to achieve this goal. Here is my mapping:
<?xml version=”1.0″ encoding=”utf-8″ ?>
<hibernate-mapping xmlns=”urn:nhibernate-mapping-2.0″>
<class name=”Palermo.Shipping.Shipment, Palermo.Shipping” table=”Shipment”>
<id name=”TrackingId” column=”TrackingId” type=”String” length=”30″ >
<generator class=”assigned”/>
</id>
<property name=”DeliveryState” column=”DeliveryState”
type=”Palermo.Shipping.DeliveryStatusType, Palermo.Shipping”/>
</class>
</hibernate-mapping>
Notice that I have a new type referenced for DeliveryState: DeliveryStatusType. This is what’s new. This type helps NHibernate map an enum string instead of the int. For this, I must define this type in my code:
public class DeliveryStatusType : EnumStringType
{
public DeliveryStatusType() : base(typeof (DeliveryStatus), 30)
{
}
}
Note that this is very simple, and the 30 specifies the max length of the enum string. I’d recommend setting this number the same as the length of your string field in your database.
With these small steps, NHibernate will now map Pending, Ready, and Sent to the database field. Normal programmatic interaction is the same. NHibernate will take care of all the data access. Without the above solution, one might be tempted to use string constants, but I’d highly recommend using enums when the possible values are known.