NHibernate Stateless Session を使用して、大量のデータをデータベースにロードしています。データが読み込まれると、後のエンティティは子コレクションに追加するために前のエンティティを検索する必要があります。この操作には、孫オブジェクトのデータが必要であり、ひ孫のコレクションが利用可能である必要があります。
基準は次のようになります。
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>();
これを実行すると、セッションの永続化コンテキスト エンティティ エントリが空であるためTwoPhaseLoad
、例外がスローされます。InitializeEntity
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
...
ローダーが検索しているエンティティは Child エンティティです。ここで永続化コンテキスト エントリ マップが空なのはなぜですか? オブジェクトは明らかにフェッチされ (正しい SQL が生成され、正しい結果が返されます)、「子」エンティティが正しく作成されます。エンティティの構築状態が正しくないのはなぜですか? ステートレス セッションが熱心な読み込み中に一時的な永続化コンテキストを使用する方法と関係がありますか?