Ayende @ Rahien

My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:


+972 52-548-6969

, @ Q c

Posts: 6,124 | Comments: 45,474

filter by tags archive

Answering Mats' Challenge

time to read 3 min | 494 words

Mats Helander has a challenge for OR/M developers, and Mats should know, since he is behind NPersist.

Go for the post for details, but basically it is loading all Customer->Orders->OrderLines graph in 3 statements or less.

Because I am a sucker for challenges, I implemented it with ActiveRecord. In Mats' terms, the code is so simple it hurts, and yes, I cheated :-)

internal static IList<Customer> LoadCustomersOrdersAndOrderLines()


    Customer[] customers = Customer.FindAll();

    Order[] orders = Order.FindAll();

    OrderLine[] orderLines = OrderLine.FindAll();

    foreach (Customer customer in customers)


        customer.Orders = new List<Order>();//avoid lazy load when adding



    foreach (Order order in orders)


        order.OrderLines = new List<OrderLine>();//avoid lazy load when adding




    foreach (OrderLine line in orderLines)




    return customers;





OK, I'm a little confused ... why was this so hard?

If the problem was basically to be expressed as "when you try and access the Orders for the Customer you will force a lazy load of the Orders" ... then I'm sure there are many solutions to the problem in many OR mappers ...

Not having looked at NPersist since Mats stopped work on it a few years ago, I can't understand why it cannot achieve the same result ...

Patrik L&#246;wendahl

"Not having looked at NPersist since Mats stopped work on it a few years ago"

That is really not true. I know for a fact that he and Roger Johansson has made numerous changes in NP the last couple of years.

Mats Helander

@ Ayende

LOL, well yes, I should have stated that the mapper should take care of resolving the references, not the client code! ;-)

But fair's fair! I'll add your entry to the list as it does fulfill the requirements in a very nice way, that I think certainly serves as a very useful, practical example of how to go about solving this yourself when the mapper won't do it for you! Well done, thanks for the contribution! :-)

However, I still contend that /NHibernate/ doesn't actually meet the challenge!

Ayende Rahien


Mats challenge was to be able to do this with just

SELECT * FROM Customers


SELECT * FROM OrderLines

It is not hard, it is just something that most OR/Ms do with joins, for reasons that are detialed in Mats' previous post.


Mats had some personal problems a while back and let those take priority. I know he has worked on it since, and I hope he has his personal life sorted out now ... his stuff is always great to read ... http://www.npersist.com/Forum/ShowThread.aspx?ThreadID=96


Ahhhhh ... now I see why it was a challenge ... with Mats clarification it wasn't to happen in client code, only within the ORM or the DB.

From the blogs Oren posted recently, it isn't surprising that he chose to resolve the problem in the client code (it is after all a business problem, not a persistence problem) - it seemed so logical to resolve the issue there, I didn't see that it was the generated SQL he wanted to see simplified :)

Mats Helander

@ Casey, Patrik

Indeed we're still working on NPersist ! I'm developing new features for it all the time, trying to stabilize old ones and actualy documenting (!) a thing or two (check the new "Inside NPersist", free download, on the website...http://www.puzzleframework.com).

However, as you say, a few years ago I did realize that I'm just not able to reliably offer support over the forums to the extent that most people would actually need, and indeed sometimes there may be six months when I just don't have enugh free time to develop NPersist at all. I'd say that info is probably more relevant to your desicions about whether to use NPersist than what new features it may have gotten since last you looked?

@ Ayende, sorry for the link mongering in your blog. Tried to keep it relevant to my response.



I really like this one.

Today at an hispanic hibernate forum which I periodically post humble opinions we were trying to figure out how we could load a tree object graph with n-level depth.

We found no answer tweaking map files or nhib cache management :(

I still guess Ayendes' cheat will do it.

Comment preview

Comments have been closed on this topic.


  1. RavenDB 3.5 whirl wind tour: You want all the data, you can’t handle all the data - about one day from now
  2. The design of RavenDB 4.0: Making Lucene reliable - 2 days from now
  3. RavenDB 3.5 whirl wind tour: I’ll find who is taking my I/O bandwidth and they SHALL pay - 3 days from now
  4. The design of RavenDB 4.0: Physically segregating collections - 4 days from now
  5. RavenDB 3.5 Whirlwind tour: I need to be free to explore my data - 5 days from now

And 14 more posts are pending...

There are posts all the way to May 30, 2016


  1. RavenDB 3.5 whirl wind tour (14):
    29 Apr 2016 - A large cluster goes into a bar and order N^2 drinks
  2. The design of RavenDB 4.0 (13):
    28 Apr 2016 - The implications of the blittable format
  3. Tasks for the new comer (2):
    15 Apr 2016 - Quartz.NET with RavenDB
  4. Code through the looking glass (5):
    18 Mar 2016 - And a linear search to rule them
  5. Find the bug (8):
    29 Feb 2016 - When you can't rely on your own identity
View all series



Main feed Feed Stats
Comments feed   Comments Feed Stats