Chapter 24. Nullables

What is Nullables?

Nullables is an add-in for NHibernate contributed by Donald L Mull Jr. (aka luggage). Most database systems allow base types (like int or bool) to be null. This means that a boolean column can take the values 0, 1 or null, where null doesn't have the same meaning as 0. But it is not possible with .NET 1.x; a bool is always either true or false.

Nullables makes it possible to use nullable base types in NHibernate. Note that .NET 2.0 has this feature.

24.1. How to use it?

Here is a simple example that uses a Nullables.NullableDateTime to (optionally) store the date of birth for a Person.

public class Person
{
    int _id;
    string _name;
    Nullables.NullableDateTime _dateOfBirth;

    public Person()
    {
    }

    public int Id
    {
        get { return this._id; }
    }

    public string Name
    {
        get { return this._name; }
        set { this._name = value; }
    }

    public Nullables.NullableDateTime DateOfBirth
    {
        get { return this._dateOfBirth; }
        set { this._dateOfBirth = value; }
    }
}

As you can see, DateOfBirth has the type Nullables.NullableDateTime (instead of System.DateTime).

Here is the mapping

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
    <class name="Example.Person, Example" table="Person">
        <id name="Id" access="field.camelcase-underscore" unsaved-value="0">
            <generator class="native" />
        </id>
        <property name="Name" type="String" length="200" />
        <property name="DateOfBirth" type="Nullables.NHibernate.NullableDateTimeType, Nullables.NHibernate" />
    </class>
</hibernate-mapping>

Important

In the mapping, the type of DateOfBirth must be Nullables.NHibernate.NullableDateTimeType. Note that NHibernate.Mapping.Attributes handles that automatically.

Nullables.NHibernate.NullableXXXTypes are wrapper types used to translate Nullables types to Database types.

Here is a piece of code using this example:

Person per = new Person();

textBox1.Text = per.DateOfBirth.Value.ToString() // will throw an exception when there is no value.

textBox1.Text = per.DateOfBirth.ToString() // will work. it will return an empty string if there is no value.

textBox1.Text = (per.DateOfBirth.HasValue ? per.DateOfBirth.Value.ToShortDateString() : "Unknown") // friendly message

per.DateOfBirth = new System.DateTime(1979, 11, 8); // implicit cast from the "plain" System.DateTime.
per.DateOfBirth = new NullableDateTime(new System.DateTime(1979, 11, 8)); // the long way.

per.DateOfBirth = null; // this works.
per.DateOfBirth = NullableDateTime.Default; // this is more correct.