I'm not clear on exactly what to do in the default constructor either. Initially I was using code like this, because that's what k-dub's MyGeneration template produced:
Code:
class Parent
{
private int m_id;
private IList m_children;
private Address m_address;
public Parent()
{
m_id = 0;
m_name = String.Empty;
m_children = new ArrayList();
m_address = new Address();
}
//...
}
That worked fine, until I had a need for a bidirectional one-to-one relationship. Obviously this didn't work:
Code:
class A
{
private B m_b;
public A()
{
m_b = new B();
}
}
class B
{
private A m_a;
public B()
{
m_a = new A();
}
}
...
A a = new A(); //Stack overflow!
At that point I read all the documentation I could find, trying to figure out what to do in these default ctors. All the examples in the NHibernate and Hibernate 2.1 docs use implicit default ctors, so I concluded it would be fine to just leave all entity object references and collections null, trusting NHibernate to initialize them properly:
Code:
class Parent
{
private int m_id;
private string name;
private IList m_children;
private Address m_address;
public Parent()
{
m_id = 0;
m_name = String.Empty;
m_children = null;
m_address = null;
}
//...
}
Unfortunately, I already had lots of code around like this:...
Code:
if( parent.Children.Count > 0 )
// Do something
...which was now producing null reference exceptions. This surprised me; I thought from the docs ("Due to the underlying relational model, [collections] do not support null value semantics; Hibernate does not distinguish between a null collection reference and an empty collection.") that NHibernate would instantiate an empty collection. I guess not. So now my default ctors look like this:
Code:
class Parent
{
private int m_id;
private string name;
private IList m_children;
private Address m_address;
public Parent()
{
m_id = 0;
m_name = String.Empty;
m_children = new ArrayList();
m_address = null;
}
//...
}
Nulls for entity object references, empty collections for collection properties, defaults (or unsaved-value, if that's different) for everything else. That seems to work for me so far, but I wish I had a better understanding of why.