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?