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)
-James

{ 18 comments }
Hey, so how do you like NHibernate? Does it seem to be saving you time?
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
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
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.
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
Nice work. This is exactly what I needed. Thanks for sharing!
Thanks James!
I had the same problem than you and your solution is great!
Thanks again
Beto
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…
I havent tried an Enum, it might make sense to try and write a custom type for Enum in general…..
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"/>
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; }
}
I can’t figure out how to map String type, any clue?
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.
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
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.
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?
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?
Where i can found that dll?
Comments on this entry are closed.