John Moore
John Moore

Reputation: 7129

Grails LazyInitializationException with collection

I see that problems akin to this have been posted before but the standard suggested solution does not appear to be working in my case, and I would like to understand why.

I have a Grails 2.2.5 application, in very active use, and I've been looking into problems with reporting where there are reasonably large data sets involved. The domain class in question is Policy, and it has a hasMany of 'events', of class Event. For a report, I do a criteria search on Policy between two dates, and then subsequently loop through the Policy objects, looking at the 'events' collection (among other fields) and building the report. This same standard technique is used elsewhere throughout the application and has hitherto proved unproblematic. Now, though, I'm seeing error messages like the following, when looping through the Policy objects:

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.blah.Policy.events, no session or session was closed

It looks as if once you get above a certain data size (in this case, around 75,000 Policy objects), session problems potentially occur. Or maybe it's to do with timeouts - it takes about 90 seconds to complete the criteria query, even though it's only using one indexed column (why??).

Anyway, I did some reading up about lazy vs eager initialization, and it seems that I should be able to tackle this issue one of two ways, either by setting 'lazy: false' for the collection in the mapping of the parent domain class, or at a query level, by setting the 'fetchMode' within the criteria, thus:

fetchMode("events",FetchMode.SELECT)

Now, a similar problem occurs in two separate places (with different collections), and in one of them I've used the domain class approach, which has solved the problem. Here, though, I don't really want to make the initialization eager everywhere, as the impact would be too large overall, I want to do it at a query level. But adding the fetchMode as above to the criteria makes no difference, I'm still seeing the LazyInitializationException, which puzzles me. Why is this not solving my problem? And why am I getting the session issues in the first place, given that with fundamentally the same code elsewhere but just with fewer results, I'm not seeing any problems?

Upvotes: 0

Views: 246

Answers (1)

Tuomas Valtonen
Tuomas Valtonen

Reputation: 508

These can be difficult to tackle. but you are definitely looking a the correct direction with the fetchMode. However, i would most likely process this whole thing in batches (if possible) which eliminates the long running query/session thing. Maybe 200 at a time. This is very easily adopted using

maxResults(maxPerBatch)
firstResult(batchOffset)

in your criteria.

If you think the query is running too long, put logSql = true in your DataSource and see what hibernate is doing and figure if you need to add fetchMode for join. Consider switching to HQL if this becomes unfixable and later even SQL.

Upvotes: 2

Related Questions