Object Relational Mappers Series - Is Your ORM Eager to be Lazy

This is the next post on my series on ORMs

Assume you fetch a ProductCategory into your ORM tool.  Logically you may decide that it would be a good idea to go ahead and iterate through the Product collection for that category.  You can either do this yourself when your app calls for it, or you can have the ORM tool do it via a mechanism most call "eager loading".  In fairness most ORM vendors will set this to disabled by default.  Why?  Remember the ORM tool is really just looping through the collection and fetching what it needs from the db which usually means that eager loading is going to send many, many SQL commands to your db.  You can usually see if this is enabled by running your application with SQL Profiler turned on.  You will likely see many additional calls that are retrieving data that is not needed.  Some ORM tools allow this to be set at the Entity level or even call level, meaning you have much finer grain control over eager loading. 

All ORM tools will have the ability to ‘lazy load’ or ‘eager load’ individual properties. ‘Lazy loading’ means not initializing properties that require pulling data from a different table until that property is referenced (just-in-time data retrieval). Eager loading means initializing these properties when the object is created and not waiting until the property is explicitly referenced. Lazy loading is generally the default with ORMs, and in most cases, lazy loading is what you want.

Remember that the ORM really has (or should not have) a lot of knowledge about your data model.  If we tried to eager load a data model with all of the correctly-declared DRI we could essentially load up most of the db.  This is because the ORM will look at every foreign key relationship being evaluated at the first select regardless of which relationships were actually being evaluated. Here is another reason why developers dislike DRI at the RDBMS level.  Explicitly marking individual properties for being eager loaded gives us more flexibility and finer control.  

But for an enterprise-class system, I still don't think that is flexible enough.  We've all worked on systems with very wide tables where only a handful of columns were required for a specific use case.  Unless you are going to have separate business objects in your ORM to handle this you will needlessly load up the extra cols into your object.  DBAs have been saying for years, "Don't use SELECT *, explicitly list your columns."  Essentially, without good planning an ORM will violate this quickly.  

In the next post, [[Object Relational Mappers Series - The N+1 SELECTs Problem]] we'll touch on another problem with ORMs that is closely related to eager loading.