Стремитесь получить коллекцию правнуков, используя сеанс без сохранения состояния через NHibernate
Я использую 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
...
Сущность, которую ищет загрузчик, является дочерней сущностью. Почему записи в контексте постоянства отображаются здесь пустыми? Объект, по-видимому, извлекается (генерируется правильный SQL и возвращает правильные результаты), а объект "Дочерний" создается правильно. Почему неверно состояние строительства объекта? Связано ли это с тем, как сеанс без состояния использует временный контекст постоянства во время активных загрузок?
1 ответ
Похоже, что это ограничение в том, как сеанс без сохранения состояния управляет контекстом временного сохранения во время двухфазной загрузки. По-видимому, в Hibernate существует исправление, которое не было перенесено в NHibernate.
https://issues.jboss.org/browse/JBPAPP-3737
Обновление:
Да, вышеуказанная проблема была проблемой и в NHibernate. Я отправил патч здесь: https://nhibernate.jira.com/browse/NH-2669