Hibernate: Scrolling through entities with lazy loaded child collections

While this should be a trivial thing, only consisting of mapping your entity and requesting a ScrollableResults from a Query object, it recently proved quite harder for me and my colleagues.

The symptoms you may see if ever using this approach are very confusing: child collections will most of the time have only one entity, the exception being apparently the first entity returned by the Query. In this regard, at least two bug reports were filed on Hibernate.org’s JIRA, #1283 and #1751.

The real deal

There’s one additional bug, already closed, that won’t come up so easily in searches regarding this matter: #1466.

On it, the submitter requested that an already initalized Collection not to be read. This feature, which is defined on the same report by Gavin King as arguable, seems to be the source of these problems.

Indeed, I recompiled Hibernate removing the lines added to CollectionLoadContext.java on #1466, and now it’s working like a charm.

It is my opinion that #1466 should be reverted. As stated on the same issue report, that’s not the correct way of working with Hibernate entities. This patch seems to be an ugly hack for one specific use case. At the very least, it should be somehow configurable.

The problematic code

To have this thing fixed, a change must be made to org.hibernate.engine.loading.CollectionLoadContext, inside the implementation of method public PersistentCollection getLoadingCollection(final CollectionPersister persister, final Serializable key).

What has to be removed is the following snippet:

if ( collection.wasInitialized() ) {
    log.trace( "collection already initialized; ignoring" );
    return null; // ignore this row of results! Note the early exit
}
else {
    // initialize this collection
    log.trace( "collection not yet initialized; initializing" );
}

This code exists from at least version 3.2.2, and is still on trunk. I’ve written on Hibernate’s JIRA commenting on this issue, but for the time being, we’ll have to live with a patched Hibernate jar.