Frans Bouma commented about lazy loading:
In general lazy loading is more of a burden than a blessing.
The reason for this is that it leaks persistent storage access to different tiers via the lazy loadable associations. If you want to prevent your UI developers to utilize lazy loading, or are sending entities across the wire to a service, how are you preventing that lazy loading is called under the hood? We support 2 models, one has lazy loading, the other one doesn't (and is more geared towards disconnected environments).
You don't really miss lazy loading in the second model really, as long as you have prefetch paths to specify prefetching what you want (also into an existing graph) The thing is that the model then forces you to write more service oriented software: make the call to the data producer and tell the data producer (or repository, whatever you want to call it) what to get and you get the data and work with it. there's no leaky lazy loading under the hood bypassing the repository, you need to call the dataproducer to get the data, period.
The problem with this approach is that pre-suppose that you are going to provide all the fetch modes in the application. I find that this is quite a burden in my applications, because I explictly don't want to deal with those concerns 90% of the time. I never quite understood the desire to protect the application from the UI developers, but that is another issue.
I have heard lazy loading described as virtual memory for data, and I agree with this description. Lazy loading is a tremendous convenience compare to the manual management of the data. If you walk into a serious performance conversation, you would often hear terms such as memory locality, minimizing paging, etc. This is after quite a bit of time with Operating Systems that take care of that transperantly. I believe that there are still people out there that do their own manual paging, but those are usually guys like Oracle and MS SQL Server.
Those are willing to take the burden of managing paging themselves, because they know hey have better knowledge of is happening, and they need this type of control. There is a reason there is such a thing as SQL OS.
For most applications, even the very big ones, trying to do that is foolhardy in the extreme. You certainly want to be aware of what is going, and you will certainly get significant performance improvements by reducing the paging patterns of the application, but you don't want to manage it yourself.
I view lazy loading in the same manner. It is something that I really don't want to live without. It is something that can cause some really bad perfomance if you are misuing it, but so can any tool in the tool box. (You had better believe that a hammer can do some serious damange).
While I don't think that we are at the same level of maturity for lazy loading as we are for paging, I definitely see this as the way we are headed. Manually loading the stuff we need is cumbersome, it is much easier to let the tools do their job, and hint them in the right direction when they don't do the right thing.