Why NHibernate Entities Need A Public Or Protected Parameterless Constructor
Posted by Davy Brion on October 4th, 2009
I have an older post where i discuss how you can implement a Value Object with NHibernate. In that post i mentioned the following:
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.
I got the following comment from someone:
I too am trying to determine how well NHibernate lives up to the promise of persistence ignorance. I can definitely live with unnecessary private constructors, but I’m dubious about adding protected constructors just to support an ORM.
At any rate, I was surprised by the sentence I quoted, because I didn’t realize there were any circumstances in which NHibernate required protected default constructors.
Once again, the answer is related to the dynamic proxies that NHibernate uses. Value Objects will never be proxied by NHibernate, so NHibernate only needs a private default constructor to create the instances. If an entity is eligible for lazy loading however, then NHibernate will create a type which inherits from your entity (this is described in depth here and here). Which means that we really need either a public or protected constructor in entity classes that are eligible for lazy loading. Consider the following class:
public class SomeEntity
{
public SomeEntity(string someRequiredValue)
{
}
private SomeEntity()
{
}
}
If we try to create the following derived class:
public class SomeEntityProxy : SomeEntity
{
}
We get the following compiler error:
Error 1 ‘ConsoleApplication1.SomeEntity.SomeEntity()’ is inaccessible due to its protection level
It’s a silly example, but it does show why entity types need at least a public or a protected default constructor and why a private one isn’t sufficient.
October 4th, 2009 at 6:40 pm
Thanks for the speedy, complete response!
I half-suspected that this was related to proxies (and ultimately, lazy-loading).
I don’t consider lazy-loading to be a requirement for entities – indeed, I’m a bit puzzled that lazy-loading is the default behavior for NHibernate mappings (and for all I know, for other ORMs). But it sounds like it’s fair to say that a private default constructor is adequate for entities too, as long as you don’t require lazy loading?
October 4th, 2009 at 6:43 pm
Yeah, that is definitely fair… and i _think_ (but am not sure) that you can use a private default constructor if you’ve disabled lazy-loading in the entity’s mapping.
October 8th, 2009 at 8:13 am
NHibernate may need default ctor
I know that it is old but it still working
http://fabiomaulo.blogspot.com/2008/11/entities-behavior-injection.html
http://fabiomaulo.blogspot.com/2009/05/nhibernate-ioc-integration.html
October 12th, 2009 at 11:44 am
Having been using nHibernate for several month, I think it is hard to maintain the mapping files.