3
votes

I'm using an NHibernate Stateless Session to load bulk data into the database. As data is loaded, later entities need to lookup previous entities in order to add them to child collections. This operation involves needing data on a grandchild object, which in turn needs a great-grandchild collection to be available.

The criteria looks like this:

var result = InternalRepository.CreateCritera<Root>()
                .SetResultTransformer(Transformers.DistinctRootEntity)
                .Add(Restrictions.IdEq(id))
                .SetFetchMode("Child", FetchMode.Eager)
                .CreateAlias("Child", "a", JoinType.LeftOuterJoin)
                .SetFetchMode("a.Grandchild", FetchMode.Eager)
                .CreateAlias("Grandchild", "b", JoinType.LeftOuterJoin)
                .SetFetchMode("b.GreatGrandchildCollection", FetchMode.Eager)
                .UniqueResult<Root>();

When I execute this, TwoPhaseLoad throws an exception during InitializeEntity since the session's persistence context entity entries are empty:

at NHibernate.Engine.TwoPhaseLoad.InitializeEntity(Object entity, Boolean readOnly, ISessionImplementor session, PreLoadEvent preLoadEvent, PostLoadEvent postLoadEvent) in TwoPhaseLoad.cs: line 64
at NHibernate.Loader.Loader.InitializeEntitiesAndCollections(IList hydratedObjects, Object resultSetId, ISessionImplementor session, Boolean readOnly) in Loader.cs: line 603
at NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) in Loader.cs: line 472
at NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) in Loader.cs: line 243
at NHibernate.Loader.Loader.DoList(ISessionImplementor session, QueryParameters queryParameters) in Loader.cs: line 1694 
...

The entity the loader is looking up is the Child entity. Why is the persistence context entries map empty here? The object is apparently being fetched (the correct SQL is generated and returns correct results), and the "Child" entity is created correctly. Why is the entity construction state incorrect? Does it have to do with how the stateless session uses the temporary persistence context during eager loads?

1
looks like they rejected your patch because it broke another unit test, did you ever get any feedback on this?David C
Yes, Fabio did include much of the patch and other fixes and improvements to stateless session as well. It is now in NH 3.2 Beta 2.codekaizen

1 Answers

2
votes

It looks like it is a limitation in how the stateless session manages the temporary persistence context during the two phase load. Apparently, a fix exists in Hibernate which has not been ported over to NHibernate.

https://issues.jboss.org/browse/JBPAPP-3737

Update:

Yes, the above issue was the problem in NHibernate as well. I've submitted a patch here: https://nhibernate.jira.com/browse/NH-2669