Mapping Enumerations with NHibernate – and hooray for open source unit tests

This is just to make a permanent note to myself.


We were using NHibernate this morning to map a class that had an enumeration type property.  By default NHibernate will store the enumeration integer value in the database.  Since this particular table will be viewed directly by support we wanted to persist the enumeration string name.  Here’s how you do it (example is taken from NHibernate itself):


Create your class that has an enumeration property:

	public class EnumStringClass
{
private int _id;
private SampleEnum _enumValue;

public EnumStringClass()
{
}

public int Id
{
get { return _id; }
set { _id = value; }
}

public SampleEnum EnumValue
{
get { return _enumValue; }
set { _enumValue = value; }
}
}

public enum SampleEnum
{
On,
Off,
Dimmed
}


Next, you need to create a subclass of the NHibernate NHibernate.Type.EnumStringType class for your custom enumeration type.

	public class SampleEnumType : NHibernate.Type.EnumStringType
{
public SampleEnumType()
: base( typeof( SampleEnum ), 10 )
{

}
}


In the NHibernate mapping you need to override the type mapping to use your new derived EnumStringType subclass. The subclass will handle the coercion from strings to enumeration.

		<property type=”NHibernate.Test.TypesTest.SampleEnumType, NHibernate.Test” name=”EnumValue” column=”enumc”></property>

Unit Tests are Documentation


There is an important underlying point here.  The NHibernate documentation isn’t all that you’d hope for and Google didn’t really help much either.  It didn’t matter because as soon as I fired up the NHibernate code I quickly found the relevant unit test that demonstrated exactly what to do.  Intention revealing unit tests are one of the best forms of technical documentation, and by definition, they can’t get out of synch with the code.  One of the best things you can do to enable the people that follow you in the code is to make your unit tests as clear as possible in the specification and usage of the code.

About Jeremy Miller

Jeremy is the Chief Software Architect at Dovetail Software, the coolest ISV in Austin. Jeremy began his IT career writing "Shadow IT" applications to automate his engineering documentation, then wandered into software development because it looked like more fun. Jeremy is the author of the open source StructureMap tool for Dependency Injection with .Net, StoryTeller for supercharged acceptance testing in .Net, and one of the principal developers behind FubuMVC. Jeremy's thoughts on all things software can be found at The Shade Tree Developer at http://codebetter.com/jeremymiller.
This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • James L

    This comes quite high up the google search results, but there’s now an easier way using generics.

    Instead of creating your own type, just use:

    name="EnumValue" column="enumc">
  • http://eashi.wordpress.com Emad

    Too late comment, but what about Globalization;
    if you have enumeration that need to be displayed in different languages?

  • http://eashi.wordpress.com Emad

    Too late comment, but what about Globalization;
    if you have enumeration that need to be displayed in different languages?

  • http://dfisla.uniblogger.com Daniel

    Thanks, another reason why both hibernate nhibernate rocks!

  • jmiller

    Sotto,

    Not at all, I just hate to have lookup tables cluttering up the database. I’d rather have the human readable values for myself for that matter.

    Jeremy

  • http://www.sotto.be sotto

    > …Since this particular table will be viewed directly by support…

    Is there a reason why you wouldn’t create a View that can be used to query that specific table?