views:

642

answers:

6

Most of what I hear about NHibernate's lazy-loading, is that it's better to use it, than not to use it. It seems like it just makes sense to minimize database access, in an effort to reduce bottlenecks. But few things come without trade-offs, certainly it slightly limits design by forcing you to have virtual properties. But I've also noticed that some developers turn lazy-loading off on certain often-used objects.

This makes me wonder if there are some definite situations where data-access performance is hurt by using lazy-loading.

So I wonder, when and in what situations should I avoid lazy-loading one of my NHibernate-persisted objects?

Is the downside to lazy-loading merely in additional processing time, or can nhibernate lazy-loading also increase the data-access time (for instance, by making additional round-trips to the database)?

Thanks!

A: 

The short version is this:

  1. Development is simpler if you use lazy loading. You just traverse object relationships in a natural OO way, and you get what you need when you ask for it.
  2. Performance is generally better if you figure out what you need before you ask for it, and ask for it in one trip to the database.

For the past few years we've been focusing on quick development times. Now that we have a solid app and userbase, we're optimizing our data access.

z5h
Total performance may be better, but sometimes large object graph loads can affect *apparent* performance, which can sometimes be a bigger deal to users.
Harper Shelby
Excellent point. Load up the basics. Display. Ajax in traversed values as needed. (for example).
z5h
+3  A: 

The usual tradeoff for lazy loading is that you make a smaller hit on the database up front, but you end up making more hits on it long-term. Without lazy loading, you'll grab an entire object graph up front, sucking down a large chunk of data at once. This could, potentially, cause lag in your UI, and so it is often discouraged. However, if you have a common object graph (not just single object - otherwise it wouldn't matter!) that you know will be accessed frequently, and top to bottom, then it makes sense to pull it down at once.

As an example, if you're doing an order management system, you probably won't pull down all the lines of every order, or all the customer information, on a summary screen. Lazy loading prevents this from happening.

I can't think of a good example for not using it offhand, but I'm sure there are cases where you'd want to do a big load of an object graph, say, on application initialization, in order to avoid lags in processing further down the line.

Harper Shelby
+9  A: 

There are clear performance tradeoffs between eager and lazy loading objects from a database.

If you use eager loading, you suck a ton of data in a single query, which you can then cache. This is most common on application startup. You are trading memory consumption for database round trips.

If you use lazy loading, you suck a minimal amount of data in a single query, but any time you need more information related to that initial data it requires more queries to the database and database performance hits are very often the major performance bottleneck in most applications.

So, in general, you always want to retrieve exactly the data you will need for the entire "unit of work", no more, no less. In some cases, you may not know exactly what you need (because the user is working through a wizard or something similar) and in that case it probably makes sense to lazy load as you go.

If you are using an ORM and focused on adding features quickly and will come back and optimize performance later (which is extremely common and a good way to do things), having lazy loading being the default is the correct way to go. If you later find (through performance profiling/analysis) that you have one query to get an object and then N queries to get the N objects related to that original object, you can change that piece of code to use eager loading to only hit the database once instead of N+1 times (the N+1 problem is a well known downside of using lazy loading).

Michael Maddox
+1  A: 

If you are using a webservice between the client and server handling the database access using nhibernate it might be problematic using lazy loading since the object will be serialized and sent over the webservice and subsequent usage of "objects" further down in the object relationship needs a new trip to the database server using additional webservices. In such an instance it might not be too good using lazy loading. A word of caution, be careful in what you fetch if you turn lazy loading of, its way to easy to not think this through and through and end up fetching almost the whole database...

Jimmy
A: 

I have seen many performance problems aring from wrong loading behaviour configuration in Hibernate. The situation is quite the same with NHibernate I think. My recommendation is to always use lazy relations and then use eager fetching statemetns in your query - like fetch joins - . This ensures you are not loading to much data and you can avoid to many SQL queries.

It is easy to make a lazy releation eager by a query. It is nearly impossible the other way round.

Alois Reitbauer
A: 

Why use NHibernate, you can write your own custom data persistence class. Ever heard of CSLA ?

HMC
Yes, I have, but I hardly believe that it's an adequate replacement for what I need Nhibernate for.
Mark Rogers