Implementing A Value Object With NHibernate
Posted by Davy Brion on March 25th, 2009
I’ve covered implementing a Value Object before, but this post is about using Value Objects with NHibernate. First, a little recap of what a Value Object is for those who don’t know yet.
A Value Object (also known as Immutable Object) is basically an object without a conceptual identity. A Value Object is defined through its inner values, and not an identity like Entities. This means that a Value Object’s inner values can not be changed after object creation, hence the term Immutable Object. Should you need to change the inner values of the Value Object, you should actually create a new Value Object.
For some of you, this might seem odd. But you’ve actually used Value Objects on many occasions already. In .NET, strings are Value Objects. So are DateTime instances. If you create a string, you can’t modify its inner value. If you do, a new string is actually created. Same thing with a DateTime. The DateTime class provides methods to add days, hours, seconds, whatever… but those methods never modify the instance’s inner value. Instead, they return a new DateTime object because each DateTime instance is immutable.
This has interesting consequences on object equality. Two Value Objects holding the same data should be considered identical objects, even though they are 2 different instances. A Value Object should therefore properly implement the Equals and GetHashCode methods.
For this example, we’ll define a Name class, which is a Value Object consisting of 2 values: FirstName and LastName. If 2 people have the same first and last name, you could say that they have the same ‘name’, right? We’ll just ignore middle names here… The combination of a FirstName and LastName would make for a good Value Object. We need to make sure that once an instance of the Name class has been created, none of its values can be modified. We also need to make sure that multiple instances of the Name class that have the same values can be safely considered equal to each other. The code of the Name class looks like this:
public class Name : IEquatable<Name>
{
private readonly string firstName;
private readonly string lastName;
public Name(string firstName, string lastName)
{
this.firstName = firstName;
this.lastName = lastName;
}
// the default constructor is only here for NH (private is sufficient, it doesn't need to be public)
private Name() : this(string.Empty, string.Empty) {}
public string LastName
{
get { return lastName; }
}
public string FirstName
{
get { return firstName; }
}
public bool Equals(Name other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return Equals(other.firstName, firstName) && Equals(other.lastName, lastName);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != typeof(Name)) return false;
return Equals((Name)obj);
}
public override int GetHashCode()
{
unchecked
{
return (firstName.GetHashCode() * 397) ^ lastName.GetHashCode();
}
}
public static bool operator ==(Name left, Name right)
{
return Equals(left, right);
}
public static bool operator !=(Name left, Name right)
{
return !Equals(left, right);
}
}
Take a close look at the constructors. The public constructor takes both required values (firstName and lastName), and assigns them to the private fields. The default constructor (which we’ve made private) merely calls the public constructor and passes String.Empty to the public constructor’s parameters. As you can gather from the comments on the private constructor, it’s only reason for existence is because NHibernate requires classes to have a default constructor. Well actually, that’s not entirely accurate since it is possible to use classes without a default constructor but it’s not trivial do so.
Creating a private default constructor seems to be a reasonable alternative. Developers can’t create invalid Name instances (unless they cheat with reflection), and NHibernate can use the private constructor so it can create the instances before it fills the fields with the values from the database.
Note: NHibernate allows a private default constructor for Value Objects, but for Entities you will need a default public or protected constructor as private is not sufficient.
We can now use this Value Object in every entity we want by simply adding a property to the entity like this:
public virtual Name Name { get; set; }
The mapping of the Value Object must be added to the mapping of the entity like this:
<component name="Name" class="NHibernateExamples.Values.Name" insert="true" update="true">
<property name="FirstName" column="FirstName" type="string" length="50" not-null="true" access="nosetter.camelcase" />
<property name="LastName" column="LastName" type="string" length="50" not-null="true" access="nosetter.camelcase" />
</component>
Notice the value of the access attribute. It’s set to nosetter.camelcase. That means that NHibernate will use the get property when reading the values, but it will use a camelcase private field to set the values when it’s creating the object with values from the database.

March 25th, 2009 at 11:32 pm
I have something similar for building a state-based workflow system except that I give my States an ID and map them to their own table. Workflow items have a State that maps to one of these “pseudo-value” objects.
I’m sure by doing that God killed a kitten somewhere, but it’s worked out well and is slightly more normalized than mapping as Components.
March 26th, 2009 at 9:37 am
[...] Implementing A Value Object With NHibernate – Davy Brion looks at the specifics of implementing value objects when using NHibernate as your persistence framework [...]
March 26th, 2009 at 10:19 am
Or you can use a base class like http://grabbagoft.blogspot.com/2007/06/generic-value-object-equality.html
March 26th, 2009 at 10:24 am
@Matt
that’s a nice approach… the default Equality and GetHashCode implementations will probably be good enough for most cases, and for those where you need better performance of Equals and GetHashCode, you can still provide an overridden optimized implementation.
April 2nd, 2009 at 8:38 am
Davy,
I have spent a good amount of time researching the use of “immutable types” with NHibernate see http://forum.hibernate.org/viewtopic.php?p=2392717
http://unhandled-exceptions.com/blog/index.php/2008/08/04/summer-of-nhibernate-session-07-exploring-mn-relationships-views-and-components/ (see comment at end)
In my opinion NHibernate + true DDD dont really fit easily!
You mention that there is a workaround to not use the default constructor. Can you elaborate a little more on this? In my opinion, in a DDD world, the domain must be completely persistence ignorant – the default constructor breaks that!
Also, we strive to ensure that all value types are in a valid state so we validate our type by performing guard checks in the ctor(within the ctor which takes in the args!). Do you not validate your value types?
This becomes even more problematic when you are retrieving a value type from the database – NHibernate instantiates the type using default ctor and sets the types properties through reflection. At the moment we use a PostLoadEventListener implementation where the constructor that has arguments is called instead. If one of the guard checks fail we throw an exception.
April 2nd, 2009 at 3:55 pm
@Billy
i believe you can avoid the need for a default constructor by using a Tuplizer, but i can’t immediately find a good link on that
about the validation… i guess it depends, if you need to validate each property on its own, you could tell nhibernate to map against private setters in the value type instead of private fields. In that case, the setters could perform some kind of basic evaluation. If you need to validate them together, then you’ll either need a custom validation method or you might get it done using the Tuplizer solution.
I agree that NH doesn’t offer 100% persistence ignorance… but i do think it’s about as close as you’ll come outside of rolling your own
April 2nd, 2009 at 4:11 pm
btw, if your application is the only thing that’s touching your database, then you could argue that value objects that are retrieved from the database (and need to be created with the default constructor by NH) should _always_ be in a valid state. If that is not the case, your own code allowed persistence of an invalid value object somewhere, which would definitely be a problem in your code.
So, if your code can guarantee that no invalid value objects are persisted, then you can still perform all the necessary guard checks in your own constructor, which would be the only one your code can use (since the default constructor would be private) and then you’d never have invalid value objects.
April 2nd, 2009 at 4:44 pm
There was a discussion/debate about this (quite a few times actually) on the NHibernate forums and DDD forum.
In my opinion, you cannot just assume that the database is correct. In 99% of applications concerning a database – some manual maintenance interaction with the database is required and just because the code guarentees value object validity when saved, you cannot assume the value object is correct.
A value type should always be in a valid state – Not validating that the type being read from the database is valid means you cannot stand over your applications value types being in a valid state!
We got around this by using PostLoadEventListener – where ctor with guard clauses is called.
April 2nd, 2009 at 8:46 pm
yeah, it’s a discussion that will probably keep going for a while
“In my opinion, you cannot just assume that the database is correct. In 99% of applications concerning a database – some manual maintenance interaction with the database is required and just because the code guarentees value object validity when saved, you cannot assume the value object is correct.”
i really think that depends on application to application. In some cases, you will be able to depend on it, in some you won’t. 99% is definitely pushing it a little bit too far, i think
in those cases where you do control the database completely, i think a private default constructor with a custom constructor which does validity checks is sufficient. If you don’t control the database completely, then the Tuplizer approach might solve some of your problems. But in that situation, you’ll probably have more things to worry about than just the validity of value objects
April 3rd, 2009 at 9:04 am
I must look into the using the Tuplizer approach!
BTW I am a major supporter of NHibernate. IMO its definitely the best ORM available for the technologies I use. I also aspire to write software using DDD methods so Im just trying my best to marry the two (NHibernate + DDD that is!)
Cheers
October 4th, 2009 at 3:49 pm
Could you elaborate on this?
October 4th, 2009 at 6:17 pm
@Jeff
hope this answers your question:
http://davybrion.com/blog/2009/10/why-nhibernate-entities-need-a-public-or-protected-parameterless-constructor/