Building objects through the constructor

28 views
Skip to first unread message

Stefan Moser

unread,
Aug 14, 2008, 11:44:35 AM8/14/08
to nhu...@googlegroups.com
I know this topic has been around for a while, but I'm wondering if someone can provide a little more detail.  Why can't NHibernate build objects through their constructors?  I know that it's a common enough request that if it were simple to implement that it would likely have already been done.
 
I want to be able to do this mostly because I try to always keep my objects in a valid state, starting with validation logic in the constructor.  This is espcially important for Value Objects (the DDD pattern) since they are immutable, so once constructed, the simply cannot become invalid.  I find that not being able to do this is one of major areas of my domain that I must implement differently because I'm using NHibernate. (read: less persistence ignorant)
 
I would be interested in having a look into the code to see if I could find a way to implement this myself, but I'm sure it's been looked at several times in the past and I would like to hear what others have found.
 
Cheers,
Stefan
 
p.s.  Sorry if this has already been posted about, searching for "constructor" returns a lot more noise than hits.

Ayende Rahien

unread,
Aug 14, 2008, 11:54:09 AM8/14/08
to nhu...@googlegroups.com
The problem is simple, NH may not have the values for the ctor by the time you create the object.
Generating a proxy is a simple example of that.

Jason Meckley

unread,
Aug 14, 2008, 1:20:14 PM8/14/08
to nhusers
to overcome the empty ctor requirement of NH
1. use chained ctors to load a default.
2. have a function to set the overridden property.

public class Entity
{
private IDependency dependency;

public Entity()
: this(new DefaultDependency())
{
}

public Entity(IDependency dependency)
{
this.dependency = dependency;
}

public void ChangeDependencyTo(IDependency somethingElse)
{
dependency = somethingElse;
}
}

or simply

public class Entity
{
private IDependency dependency = new DefaultDependency();

public Entity()
{
}

public void ChangeDependencyTo(IDependency somethingElse)
{
dependency = somethingElse;
}
}

On Aug 14, 11:54 am, "Ayende Rahien" <aye...@ayende.com> wrote:
> The problem is simple, NH may not have the values for the ctor by the time
> you create the object.
> Generating a proxy is a simple example of that.
>

Roger Kratz

unread,
Aug 14, 2008, 3:27:59 PM8/14/08
to nhu...@googlegroups.com
<<I want to be able to do this mostly because I try to always keep my objects in a valid state, starting with validation logic in the constructor.>>

Without knowing anything about your domain, are you sure you really want to force your objects to always be in a valid state? I could only speak for myself here, but I've went from having "your" opinion to be much more open minded having aggregates in illegal state the last few years. Normally I impl these stuff using some state pattern telling if the aggregate is valid or not. In most cases, I like this much better.

(this got nothing to do with your question but...)
<<This is espcially important for Value Objects (the DDD pattern) since they are immutable>>
DDD does not state that value objects _must_ be immutable, as long as it's not shared/used by multiple objects.

/Roger

________________________________
winmail.dat

Stefan Moser

unread,
Aug 14, 2008, 1:58:33 PM8/14/08
to nhu...@googlegroups.com
Jason, it's not necessarily dependencies that I'm worried about.  A common pattern I like to use if validating Value Objects in their constructors.  Since they're immutable, they simply cannot become invalid, ever. 
 
public class Address
{
    private int _streetNumber;
    private string _street;
    private string _zipCode;
    private string _city;
 
    public Address(int streetNumber, string street, string zipCode, string city)
    {
        // this is the ONLY constructor, the only way the object can be instantiated
        // validate that the street number is not negative, zip code is correct format etc
    }
}
 
I know, this is a very contrived example, but I hope it gets the point across.  Once the object is created, I never have to check that it is valid.  You'll never see a guard clause in a method that takes a Value Object to check that it's valid.
 
Using NHibernate, these are usually mapped as a component, so maybe there's so hope there, but this doesn't mean that the same concept doesn't apply to Entities as well.  I try to take the same approach on all objects.
 
Anyway, the point of my original post wasn't to discuss Value Objects, validation, dependencies or work arounds.  I just wanted to know what was stopping me from using a style of coding that I'm comfortable with when using NHibernate as my persistence tool.  Ayende's comment was helpful and I will still have a look inside the code when I get the time to try and understand the issue a little more.
 
Cheers,
Stefan

Nathan Stott

unread,
Aug 14, 2008, 5:56:11 PM8/14/08
to nhu...@googlegroups.com
Well, make a private constructor.

Then the only way anything but nhibernate can create it is with your
validating ctor and you can assume that anything instantiated by
nhibernate using the private ctor is valid because of this.

Stefan Moser

unread,
Aug 14, 2008, 6:53:01 PM8/14/08
to nhu...@googlegroups.com
Getting a little off topic, see the DDD list for more discussion: http://tech.groups.yahoo.com/group/domaindrivendesign/message/7942

Greg Young

unread,
Aug 14, 2008, 7:16:46 PM8/14/08
to nhusers
I recently had this same discussion with the EF team over at
Microsoft. Yes this is a "workaround" but let's look more in depth at
it.

So how do I validate my object when nHibernate loads it? After its
hydrated do I have some "Validate()" method that I call externally?
Value Objects should be verified when being loaded from persistence. A
Value Object can never be in an invalid state. This becomes especially
important when sharing value objects.

As an example I have a PhoneNumber value object. It gets loaded from
persistence with invalid data. The big problem I run into here is that
my code assumes that the value object is valid and I share the value
object ex:

Client.PhoneNumber = Purchaser.PhoneNumber; //oops
Purchaser.PhoneNumber was loaded with an invalid state and now I just
set that same invalid state to another object.

Since we don't want this to be able to happen we need to insure state
when loading from persistence. Or begin sprinkling "Validate" calls
throughout our code.


To have the private constructor requires me to have two separate
validation stories for every value object. One for when it is
constructed by my code, one for when nhibernate is loading the
object .... What was that "Persistence Ignorance" thing that keeps
getting thrown around?

Cheers,

Greg

On Aug 14, 2:56 pm, "Nathan Stott" <nrst...@gmail.com> wrote:
> Well, make a private constructor.
>
> Then the only way anything but nhibernate can create it is with your
> validating ctor and you can assume that anything instantiated by
> nhibernate using the private ctor is valid because of this.
>
> > On Thu, Aug 14, 2008 at 10:20 AM, Jason Meckley <jasonmeck...@gmail.com>

Greg Young

unread,
Aug 14, 2008, 7:10:11 PM8/14/08
to nhusers
You are technically correct, DDD "highly recommends them being
immutable" as otherwise they can't be shared.

but... what is the point of having a value object if you can't share
it?

What exactly will you be doing with said value object? Said Value
Object quickly starts smelling like an entity.

Cheers,

Greg
>  winmail.dat
> 6KViewDownload

Nathan Stott

unread,
Aug 14, 2008, 7:43:54 PM8/14/08
to nhu...@googlegroups.com
If you only allow access to the database from your application, you
will not end up with invalid data in the database.

Sure maybe there are edge cases where you will, but there are edge
cases to everything in software engineering. >99% of the time, if you
have a public ctor that validates and a private ctor with no args for
NHibernate to use, your value objects will be in a valid state.

Greg Young

unread,
Aug 14, 2008, 7:46:21 PM8/14/08
to nhu...@googlegroups.com
> If you only allow access to the database from your application, you
> will not end up with invalid data in the database.
>

I take it this is because:

1) Validation never changes over time
2) Programmers are infallible

--
It is the mark of an educated mind to be able to entertain a thought
without accepting it.

Nathan Stott

unread,
Aug 14, 2008, 7:51:05 PM8/14/08
to nhu...@googlegroups.com
If your validation changes on your objects, I'd recommend running an
ETL to translate your persisted objects into a valid state. Cowboy
loading them from the DB and then correcting the invalid state would
be the wrong practice here imo.

Also, programmers are not infallible, but this is why we have unit
tests during development and staging areas before moving to
production.

Therefore, I stand by my statement that if you have a public ctor that
validates and a private ctor for NHibernate to use, and nothing else
touches the datastore, then >99% of the time your entities will be
valid when loaded from NHibernate.

Ayende Rahien

unread,
Aug 14, 2008, 8:11:16 PM8/14/08
to nhu...@googlegroups.com
3) no one is ever tempted to manually touch the database

Ayende Rahien

unread,
Aug 14, 2008, 8:11:46 PM8/14/08
to nhu...@googlegroups.com
Doesn't matter if it is 99%.
You still have to deal with the 1%

Nathan Stott

unread,
Aug 14, 2008, 8:39:40 PM8/14/08
to nhu...@googlegroups.com
My general point is that the 1% case does not spoil the solution even
though you have to deal with it.

Linq to SQL, EF, and NHibernate all require the empty ctor, so this is
a (small) problem that we have to tolerate.

Ayende Rahien

unread,
Aug 14, 2008, 8:50:09 PM8/14/08
to nhu...@googlegroups.com
The problem with the 1% is that you have to code & test for that. Very often, its cost outwieght the benefits.

Greg Young

unread,
Aug 14, 2008, 9:08:43 PM8/14/08
to nhu...@googlegroups.com
Actually this is something that might be changing for EF v2 ... Not
sure if its actually going to be done or not but there was discussion
about it.

Nathan Stott

unread,
Aug 14, 2008, 9:09:42 PM8/14/08
to nhu...@googlegroups.com
It'd be great if we one day saw NHibernate not require the
paramaterless ctor. Until then, what's your suggested pattern, Oren?

Colin Jack

unread,
Aug 15, 2008, 3:43:54 AM8/15/08
to nhusers
> but... what is the point of having a value object if you can't share
> it?

> What exactly will you be doing with said value object? Said Value
> Object quickly starts smelling like an entity.

I actually find they have a lot of value beyond just sharing, in
particular the fact that they are always valid simplifies my overall
validation because I know if I have an Address its valid so I don't
need to keep re-validating it.

Plus in legacy systems you may not have a choice. For example lets say
you have two Customers living at the same Address but for whatever
reason the address columns are in the Customer table, they're going to
have seperate objects.

Billy Stack

unread,
Aug 15, 2008, 3:37:28 AM8/15/08
to nhu...@googlegroups.com
I recently posted about immutable types in the nhibernate forums as well. I was pushing for using NHibernate as an ORM where our domain entities are immutable.
 
The last leg left in our development phase was persisting to the database where NHibernate was chosen as the favoured ORM to use. However I failed to persuade the rest of the development team to use NHibernate simply due to "persistence ignorance". Having all of our domain entities defined (and there are quite a few of them), why should we have to change our domain entity definitions to suit a particular ORM?
 
As we definitely were not changing our domain entities, the only other option was to map each of our immutable types to NHibernate friendly type equivalent, however keeping two sets of entities (domain and data layer) in tandem would prove too expensive in my opinion.
 
I am currently looking at the NHibernate code base to see how it depends on the default constructor etc but overall I'm very surprised this "immutable" type issue with ORMs isn't more prominent!

Colin Jack

unread,
Aug 15, 2008, 3:50:23 AM8/15/08
to nhusers
> So how do I validate my object when nHibernate loads it? After its
> hydrated do I have some "Validate()" method that I call externally?
> Value Objects should be verified when being loaded from persistence. A
> Value Object can never be in an invalid state. This becomes especially
> important when sharing value objects.

Your making a great point. I've always relied on the idea that if the
VO was valid when I saved it then it was valid when I reload but you
are bang on, you cannot assume that. In fact I've recently worked on a
system with a legacy DB and really assuming that we put in was what we
were going to get out wasn't entirely safe (especially as, like you
say, validation rules change).

And as you say there is no real work around as I'm not going to load
back in the VO and validate it once NHibernate loads it.

So whilst the PI doesn't bother me a massive amount (think Nilsson was
quite right in that section of his book) I think you are spot on.
Reply all
Reply to author
Forward
0 new messages