Must Everything Be Virtual With NHibernate, Part II
Posted by Davy Brion on September 23rd, 2009
I already tried to explain this before, but here’s a simple example from a presentation i recently did on NHibernate:

As you can see, only the properties of associations that are eligible for lazy-loading are virtual in this piece of code, because that is what many people seem to want. There are actually 2 different ways in which this can cause problems… can you spot both problems?

September 23rd, 2009 at 8:11 am
The Date property must also be virtual, in case an Order is being lazy-loaded as a reference from a Customer or Employee. At run time the Customer/Employee will have a proxy at hand, and will need to initialize it whenever an attempt to get the Date is made.
I am not sure about this, but maybe we also need to access the customer using the property (Customer) and not the field directly.
Wouldn’t working with interfaces all around (IOrder, ICustomer, IEmployee) make everything more transparent? The runtime proxy will implement the interface, instead of inheriting from the class, and the property calls will pass through it to the real object (after initialization) ? I remember using this method in Hibernate. Is it also available on NHibernate?
September 23rd, 2009 at 8:54 am
Yeah, you can also use interfaces to avoid virtual methods with NHibernate
the Date property should indeed be virtual, but that’s not the actual problem that i’m trying to show here
accessing the customer through the property instead of the field would indeed change everything
September 23rd, 2009 at 12:25 pm
I would say that the two methods (AddOrderLine and RemoveOrderLine) need to be virtual. Not sure why, but everytime I have one of these methods and I forget to put virtual around these, I get errors during Factory configuration.
If I was to guess a reason it would be because of OrderLines is lazy loaded.
September 23rd, 2009 at 1:00 pm
yeah, they need to be virtual… but why? what can go wrong if they aren’t?
September 23rd, 2009 at 3:28 pm
Customer is virtual (lazy loaded), customer is null until Customer is loaded. customer.DiscountPercentage will return a null reference exception if Customer hasn’t been loaded. This is a good example of why static methods can prevent side-effects.
September 23rd, 2009 at 4:07 pm
This feels like a fabricated example, why are you using a field-backed property instead of the auto property? If the expectation is that your property is lazy-loaded then it should not necessarily come as a surprise that your field is not.
That doesn’t mean it’s not something that people would make mistakes against or that I don’t agree to what you say
September 23rd, 2009 at 4:30 pm
Field-backed properties are useful when you want to make the variable static or readonly. In this case, I agree that the auto-getter/setter makes the code more straightforward.
September 23rd, 2009 at 8:13 pm
Apart from Customer/customer -> has to be Customer, as already stated in the comments. There’s still the ‘Why do AddOrderLine and RemoveOrderLine need to be virtual’?
Well, you kinda pointed out the solution in your _before_ link
They have to be virtual so the proxy generated by NHibernate can override them, adding some lazy loading mojo to it.
September 23rd, 2009 at 10:02 pm
Seems a slightly contrived example to me.
I can buy that to get lazy loading the properties would require them to be virtual. But why must methods also be virtual? I can see in your example that side stepping the property and accessing the field behind it will also side step the lazy loading.
My response… Don’t do that then.
If you want lazy loaded properties then only use the properties. This is the same problem as when you have _any_ logic inside the getter/setter.
So, why does NH need access to the internals of my methods? What, exactly, does NH _do_ to the code? If I _always_ use properties and not fields, what is there extra for NH to do?
September 27th, 2009 at 7:45 pm
[...] Must Everything Be Virtual With NHibernate, Part II [...]