NHibernate and nullable value types.

If I were designing a database from scratch, I'd avoid nullable columns like The Plague.  Unfortunately, a lot of legacy (and not-so-legacy) databases tend to have nullable columns.  Kinda sucky if you're doing NHibernate development under .NET 1.1 because you have to have to do a extra stuff to make it work. 

In preparation for my NHibernate talk at VSLive San Francisco, I needed to learn how to actually map that scenario.  Then I started thinking about the new nullable value type syntax in .NET 2.0 (int? myInt32 = null; DateTime? myDateTime = null;) and wondering well how that would work with NHibernate. 

So, I wrote up some unit tests and some sample classes to try it out. 

The .NET 1.1 way using the NHibernate nullable DLLs was a lot easier to work with than I expected.  Any value-type property on  your entity classes just needs to be the appropriate type from Nullables.dll (ex. DateTime --> NullableDateTime, int --> NullableInt32) and in the mapping file you have to add a “type“ attribute to the appropriate “property“ elements.

The nice thing is that when you access the properties on your entity classes, you really don't have to be all that aware that they're anything other than the regular .NET value type.  You can just assign to them and compare them pretty much as normal...no mucking around with new'ing up instances of Nullable types in order to do assignments.  Example: temp.NullableBool = false;

The .NET 2.0 way is even less intrusive.  In your entity classes, mark the property datatype as nullable using the “?“ syntax and in your mapping file you don't have do anything special at all.  It just works. 

Anyway, I've posted the test project and sample classes are here.  Make sure to check the database connection string in “hibernate.cfg.xml“ in the NHibernateResearch.VisualStudioTests project.  Also, since the tests do drop and create database tables, you might want to create a blank database and point hibernate.cfg.xml's connection string to that new database. 

Enjoy.

-Ben

posted @ Saturday, December 10, 2005 12:51 PM

Print

Comments on this entry:

# re: NHibernate and nullable value types.

Left by Paulo at 12/12/2005 8:32 AM
Gravatar
i Ben,

i dont like Nullables DLL approach because it forces you to use a "non-native" value type and tight your model to NHibernate.

So, searching via Google :) i found a Nullables DLL version 2, wich allow you to use something like: bool _myvariable instead of Nullablebool _myvariable.

See this link: http://dotavery.com/blog/archive/2005/09/30/5202.aspx

looking in NHibernate forum, KPixel said Nullables2 will be added to the core soon.

# re: NHibernate and nullable value types.

Left by Benjamin Day at 12/12/2005 8:51 AM
Gravatar
I agree, I'm not super thrilled about using the Nullable.dll in 1.1, either. The nice thing is that it's been replaced with 2.0 so we won't have to deal with it all that much longer.

I'll have to check out that blog entry in a little more detail later. It looks like James Avery is saying that NHibernate doesn't handle the "?" nullable syntax.

That seems weird to me because my tests with "?" worked just fine with ordinary property mappings....no "type" required.

Maybe I'm missing something or I've got errors in my tests.

BUT! Even if you do have to do the 1.1 nullables.dll method, it's not really an NHibernate specific problem or solution. Even if you weren't using nhibernate, you'd still have to solve the problem of needing a nullable valuetype....that's a limitation in Framework 1.1.

-Ben

# re: NHibernate and nullable value types.

Left by Mat at 3/28/2006 2:07 PM
Gravatar
Hi Ben,

Did you take a look at James Avery's blog entry regarding the ? syntax?

I've found I'm unable to use the ? nullable syntax in the .hbm.xml file. I get an exception "could not interpret type: System.DateTime?" Neither can I use the Nullable<System.DateTime> syntax ("'<', hexadecimal value 0x3C, is an invalid attribute character. Line 11, position 49." exception).

Ignoring the nullable entirely in the mapping file appears to work at first (every record in that column of my database contained null) but once actual data is present too it falls over. The exception in this case is {"Unable to perform find"}. {"GetBytes can only be called on binary columns"}. As far as I can see, something's causing NHibernate to treat nullable property/field as a NHibernate.Type.SerializableType.

-Mat

# Avoiding Nullable Types

Left by Lenny at 4/16/2006 9:14 PM
Gravatar
With your statement abve.
"If I were designing a database from scratch, I'd avoid nullable columns like "

What would you do if you had a StartDateTime and EndDateTime?

# re: NHibernate and nullable value types.

Left by Benjamin Day at 4/17/2006 6:51 AM
Gravatar
The start/end time structure is one that often isn't practical to implement as non-nullable.
I suppose you could do it using a "magic" value in the database like '1/1/1900' to indicate null but that's not really all that great of a solution.

In your case, I think I'd just go with the nullable column.

-Ben

Your comment:



 (will not be displayed)


 
 
 
Please add 6 and 2 and type the answer here:
 

Live Comment Preview: