Performance and Explicit Domain Models

time to read 3 min | 446 words

Udi talks about limitations for DDD as a result of performance constraints. He says:

Ayende and I had an email conversation that started with me asking what would happen if I added an Order to a Customer’s “Orders” collection, when that collection was lazy loaded. My question was whether the addition of an element would result in NHibernate hitting the database to fill that collection. His answer was a simple “yes”. In the case where a customer can have many (millions) of Orders, that’s just not a feasible solution.

He then goes on to describe several solutions for the issue, including [ThreadStatic] events, something I have never consider but has some interesting possibilities.

I wanted to add another option to the mix. You can extend NHibernate so calling customer.Orders.Add( new Order() ) will not force a load of the collection if the collection is not loaded, but would still add the new order to the unit of work.

What is the caveat? It violates the principal of least surprise.

My NHibernate.Generics collection used to do just that, I did it on the belief that it would save performance in un-needed trips to the database. I paid for that performance in grief when I found bugs where this failed:

   1:  customer.Orders.Add(new Order())
   2:  // sometime later, still in the same Unit of Work
   3:  if(customer.Orders.Contains(theOrder)==false)
   4:  {
   5:    //do something bad
   6:  }
 
Basically, the order was not persisted yet, and when the collection was loaded from the database, it didn't include the newly added instance, which caused quite a bit of confusion. We have run into it several times, and it convinced me that I really shouldn't do things that would surprise the naive developer, since that tends to be me.
 
I wanted to mention this, since it is a viable alternative for this scenario, since you aren't likely to load the Orders collection any time soon anyway.