NHibernate + XML Columns

One of the things I’ve been working on recently involves using XML columns in SQL Server.  Starting out, it was simple and I was just doing vanilla ADO.NET (wrapped in a simple Query API) combined with XML serialization/deserialization, which worked pretty well for a while. 

But as the complexity has grown, it seemed like too much time was being spent enhancing the persistence infrastructure in this particular area of the application.  In comes NHibernate, which is already integrated and available to me on this particular project.  In fact, the only reason I didn’t use NHibernate for this particular feature from day one is because I didn’t see a lot of information available regarding NHibernate and XML columns.  I did find one old blog post by Ayende and a seemingly outdated article on the NHibernate site.  But I admit I’ve never jumped into creating custom user types in NHibernate and wasn’t yet comfortable moving forward with that approach.  Since what I needed at the time was pretty simple, I went forward without NHibernate for the time being.

Without going into too much detail, I came to a point where I wanted to spike with NHibernate to see how it handles columns with an XML data type.  I’ve only tried one of a couple approaches so far, but wanted to get some feedback on it so far.

First, a couple goals:

  • Store a set of data as XML in a SQL Server XML column
  • Ability to deserialize the XML into strongly typed objects for use in the rest of the code base

Warning: contrived example ahead.  The real implementation is basically for lightweight messages.

   1: public class Person
   2: {
   3:     private readonly string contactInformationXml;
   5:     public Person(ContactInformation contactInformation)
   6:     {
   7:         // NOTE: SerializeToXmlStream extension method not shown
   8:         contactInformationXml =
   9:             new StreamReader(contactInformation.SerializeToXmlStream()).ReadToEnd();
  10:     }
  12:     public ContactInformation GetContactInformation()
  13:     {
  14:         var xmlDocument = new XmlDocument();
  15:         xmlDocument.Load(contactInformationXml);
  17:         // NOTE: DeserializeInto extension method not shown
  18:         return xmlDocument.DeserializeInto<ContactInformation>();
  19:     }
  20: }

And an excerpt from an example NHibernate mapping for this:

   1: <property name="ContactInformationXml" column="ContactInformation" 
   2:           type="String" not-null="true" access="field.camelcase" />

So in the Person class above, the constructor accepts a strongly typed component for the contact information, serializes it to XML and stores it in a private field as a string.  Then the NHibernate mapping takes care of persisting the serialized string to the XML column named ContactInformation in the database.  To see how it would get used when NHibernate loads a Person, the GetContactInformation() method is an example of deserializing the string into the strongly typed ContactInformation object which it then returns.

Now, putting aside the reasons for or against using XML in this way, using XML columns in general or the fact that serialization concerns shouldn’t be placed inside a class like this…

I’m looking for feedback on this approach and if anyone else has any better ways of doing this.  I’ve yet to go down the path of creating a custom NHibernate user type, even though I think doing it that way would be a bit cleaner and flexible in the future.

Anyone have any other good examples of using NHibernate for persisting data to XML columns?

This entry was posted in nhibernate. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

6 Responses to NHibernate + XML Columns

  1. Derek Ekins says:

    You might want to check out this thread http://markmail.org/message/wae5qe5b2kti4qqd
    There is even a user type there you can use.

  2. Harry M says:

    Interesting. I’ve just writen a generic IUserType that persists an object as XML to an NVARCHAR(MAX) column which I’m using with Fluent NHib. I thought it as a bit useless as I couldn’t index on the properties, but maybe I will be able to if I use an XML column. Up on my blog in the next couple of days.

  3. Jason says:

    an IUserType would be the way to go. The domain shouldn’t care that ContactInfo is actually stored as XML, so the entity shouldn’t know about that. the 2 important members of IUserType are SafeGet and SafeSet which is where you would place the (de)serialization logic. the mapping would then get updated to then there is no need for field access.

  4. @Jason,
    Cool, thanks Jason! I would agree that the domain entity shouldn’t know about this type of information. In the real example, it’s not necessarily domain entities doing this, it’s really just messages. But yeah, I think I will have to take a further look into solving it with an IUserType.

  5. J Healy says:

    XML column use is of general interest as one plausible approach to the data extensibility requirements associated with shared database SaaS instances and other MEBA apps. Good to see a rundown of the use with NHibernate.

  6. Tobin Harris says:

    Here’s one I’m using at the moment, it lets you map XmlDocument properties on classes directly to database columns, using a UserType.


    Feel free to post improvements and updates.