NHibernate and .NET 2.0 Nullable Types

by javery on October 1, 2005

On both my latest contract and an open source project I am working on we are using both .NET 2.0 and NHibernate. While NHiberate works just fine with 2.0, there is no native support for nullable types. There are some nullable types built into NHibernateContrib, but we would have to use their types instead of the normal .NET 2.0 types… this seemed like a bad solution. We tried a couple different options, but finally ended up with modifying the NHibernateContrib types to use the native .NET 2.0 types. I made a couple other small changes to the contrib code as well. Now you can do this in your mapping file:

<property name=TestBool column= boolCol type=NHibernate.Nullables2.NullableBooleanType, NHibernate.Nullables2 />

The property TestBool is declared as “bool?” in the class, not a special nullable type.

This is really just a temporary solution until NHibernate is revised to include native support for these types, but if you are running into the same problems feel free to download it and give it a try. (let me know if you find any bugs or have any fixes)

Download Code.

-James

{ 18 comments }

Haacked October 1, 2005 at 4:04 am

Hey, so how do you like NHibernate? Does it seem to be saving you time?

James Avery October 2, 2005 at 5:52 pm

It’s too early to tell, but I think it should be a big time-saver especially since we are working with some agile data requirements. :)

-James

OtherOneOfTheTowWisemen October 13, 2005 at 9:22 am

Hello!

Trying to combine the new release of NHibernate 1.0 with your modification ob NHibernateContrib failed. Is it possible to configure Nullables2 to work with this new release, or are you planning to adapt Nullables2??

Thanks for any advice.

OtherOneOfTheTowWisemen

Scott Beeler October 18, 2005 at 3:47 am

OtherOneOfTheTowWisemen,

I downloaded James’ code, copied in the new 1.0 release dlls to the NHibernate Files directory, rebuilt the Nullable2 solution, and everything works great.

James,

THANK YOU! The lack of nullable support in NHibernate was killing me. Using the Nullables from NHibernateContrib was a lousy option. Have you contributed this to the NHibernate developers? Your solution is just what I was looking for.

Michele Perrone October 28, 2005 at 12:12 pm

public override bool Equals(object x, object y)

{

//get boxed values.

DateTime? xTyped = (DateTime?)x;

return xTyped.Equals(y);

}

Hello,

Above code fails when x and y are null.

I am trying to add a new record in the database without any value.

All columns in the sql table are nullable.

Somebody knows if I am doing something wrong?

Thanks in advance,

Michele

Brent Brown November 8, 2005 at 11:35 pm

Nice work. This is exactly what I needed. Thanks for sharing!

Beto November 9, 2005 at 9:22 pm

Thanks James!

I had the same problem than you and your solution is great!

Thanks again

Beto

Nathan December 3, 2005 at 5:39 am

How might you map a Nullable Enum? If I try and map it as its underlying type (NullableInt32) it throws an exception. If I leave the mapping and don’t specify the type it works, but when a value is specified it ends up being stored as a VARBINARY(8000) instead of the Int32…

James Avery December 3, 2005 at 2:25 pm

I havent tried an Enum, it might make sense to try and write a custom type for Enum in general…..

Nathan December 3, 2005 at 6:36 pm

Here is a workaround for Enums:

Declare a private property of type int? and then map this property in your mapping file.

Here is the class:

private State? state; // Nullable Enum

public State? State

{

get { return this.state; }

set { this.state = value;}

}

private int? StateValue

{

get { return (int?)this.state; }

set { this.state = (int?)value; }

}

Here is the property mapping:

<property name="StateValue" column="State" type="NHibernate.Nullables2.NullableInt32Type, NHibernate.Nullables2"/>

Nathan December 3, 2005 at 6:38 pm

Sorry, the StateValue property had an incorrect cast, should be (cast to State? not int?):

private int? StateValue

{

get { return (int?)this.state; }

set { this.state = (State?)value; }

}

Panthony December 27, 2005 at 9:59 pm

I can’t figure out how to map String type, any clue?

RichardP February 16, 2006 at 3:23 am

String is not a ValueType in the first place. It’s immutable, but not a ValueType. You don’t need any special handling of .NET null, though your database may be treating empty strings as null and that can cause you problems. For that, I just wrote a quick interceptor to convert all empty string values to actual .NET null on Update and Insert.

ragundo February 20, 2006 at 6:24 pm

Hi. I get an error

WRN: Comparing the assembly name resulted in the mismatch: PUBLIC KEY TOKEN

when using your nullable types.

My nhibernate is 1.0.2.0 with PublicKeyToken = 154fdcb44c4484fc. Using reflector with your assembly, nhibernate is referenced with a null PublicKeyToken.

Could this the reason ?, I’ve copied the last Nhibernate files to your solution Nhibernate dir and compiled everyting with VS2005 ( worked fine ).

Greetings from Spain

Mat March 28, 2006 at 8:46 pm

I couldn’t get the ? syntax to work within the XML mapping file as suggested at http://blog.benday.com/archive/2005/12/10/3526.aspx, so have been struggling trying to get it working as suggested above for a couple of hours, and then chanced upon this blog post:

http://frazzleddad.blogspot.com/2005/10/more-on-nhibernate-and-nullables_20.html

If anyone else is having trouble, make sure you’ve built NHibernate.Nullables2 with the files in NHibernate Files replaced with the version of NHibernate’s files you’re using in the rest of your project.

Ngoc Dinh January 17, 2008 at 6:52 am

Server Error in ‘/web’ Application.
could not interpret type: NHibernate.Nullables2.NullableBooleanType, NHibernate.Nullables2
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: NHibernate.MappingException: could not interpret type: NHibernate.Nullables2.NullableBooleanType, NHibernate.Nullables2

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[MappingException: could not interpret type: NHibernate.Nullables2.NullableBooleanType, NHibernate.Nullables2]
NHibernate.Cfg.HbmBinder.GetTypeFromXML(XmlNode node) +545
NHibernate.Cfg.HbmBinder.BindSimpleValue(XmlNode node, SimpleValue model, Boolean isNullable, String path, Mappings mappings) +15
NHibernate.Cfg.HbmBinder.PropertiesFromXML(XmlNode node, PersistentClass model, Mappings mappings) +692
NHibernate.Cfg.HbmBinder.BindRootClass(XmlNode node, RootClass model, Mappings mappings) +2404
NHibernate.Cfg.HbmBinder.BindRoot(XmlDocument doc, Mappings mappings) +392
NHibernate.Cfg.Configuration.AddValidatedDocument(XmlDocument doc, String name) +55

[MappingException: Could not compile the mapping document: Winbooks.OM.NP.Hbm.NPUser.hbm.xml]
NHibernate.Cfg.Configuration.LogAndThrow(MappingException me) +38
NHibernate.Cfg.Configuration.AddValidatedDocument(XmlDocument doc, String name) +121
NHibernate.Cfg.Configuration.AddInputStream(Stream xmlInputStream, String name) +115
NHibernate.Cfg.Configuration.AddResource(String path, Assembly assembly) +177
NHibernate.Cfg.Configuration.AddResources(Assembly assembly, IList resources, Boolean skipOrdering) +155
NHibernate.Cfg.Configuration.AddAssembly(String assemblyName) +145
NHibernate.Cfg.Configuration.DoConfigure(XmlDocument doc) +640
NHibernate.Cfg.Configuration.Configure(XmlTextReader reader) +308
NHibernate.Cfg.Configuration.Configure(XmlNode node) +73
NHibernate.Cfg.Configuration.Configure() +32
NHibernatorFramework.NHibernator..cctor() +526

[TypeInitializationException: The type initializer for 'NHibernatorFramework.NHibernator' threw an exception.]
NHibernatorFramework.OpenSessionInViewModule.Init(HttpApplication context) +121
System.Web.HttpApplication.InitModulesCommon() +66
System.Web.HttpApplication.InitInternal(HttpContext context, HttpApplicationState state, MethodInfo[] handlers) +1006
System.Web.HttpApplicationFactory.GetNormalApplicationInstance(HttpContext context) +259
System.Web.HttpApplicationFactory.GetApplicationInstance(HttpContext context) +114
System.Web.HttpRuntime.ProcessRequestInternal(HttpWorkerRequest wr) +350

It cannot work with NHibernate.dll (1.2.0.4000). Can you help me?

Axl January 25, 2008 at 9:39 pm

Are the NHibernate.Nullables2 classes for the most part the same as the NHibernate.UserTypes.SqlTypes classes in NHibernate 1.2, or should/can they be used differently?

pp June 25, 2009 at 10:09 am

Where i can found that dll?

Comments on this entry are closed.

Previous post: September Books

Next post: Prefactoring