dia100 wrote:
If I fetch all data say for object A, this means I don't have lazy anymore.
Pre-fetching all lazily initialized data is not a proper solution, since - as you stated - the data is really "lazy" anymore. If your application has a rich object model having huge number of associations, pre-fetching lazy collections can be a major performance issue.
Our example application is a group calendaring application running on Hibernate2, Struts 1.2 and Velocity 1.3. We are using the ThreadLocal-based design pattern for handling Hibernate sessions, so the session is kept alive for the lifespan of one HTTP request. However, sometimes we need to put data in the HTTP session for quick access and it introduces problems on objects which refer to lazily initialized collections. Here's one example use case:
1) User wants to perform an event search, trying to find all events occurring in February.
2) 186 events are matched, so the results must be paged. Application renders 10 results per page, which means that 19 result pages are created.
3) The result pages are stored in user's HTTP session for quick access, allowing the user to move to another result page quickly, since the action class won't need to perform the database search again.
Stale data is not a problem for us: if user decides to open one of the listed events, the event will be loaded from the database, and not picked from the memory-resident collection.
The event object contains references to three collections: attendees (users or groups), attachments and resources (like meetings rooms or vehicles). We certainly want to keep these collections lazy, because the overall amount of data loaded would be excessive otherwise. This wouldn't be a problem if we only needed to access the basic information of the event (such as event name, location, start date and end date), but we also need to perform fine-grained access control when we try to find out which actions user can perform on the event.
Access control introduces problems because the controller needs to access these lazily initialized collections in certain conditions. For example, in our access control policy a user can view event's details only if any of the following conditions are met:
1) User is the owner or the creator of the event
2) The event has public visibility
3) The event has attendee visibility and the user (or one of the groups the user belongs to) is on the attendee list of the event
If the controller falls back to condition 3, it needs to access the lazily initialized collection (event attendees). If this is performed on the result page number two, the controller throws an exception because Hibernate session is not alive anymore.
It is very likely that the user never browses to a result page beyond number two. Therefore it wouldn't make sense to pre-fetch these collections in advance, resulting in a huge object-graph to be loaded in and never being used. There must be a better alternative.