Быстрая выборка коллекции правнуков с использованием сеанса без состояния через NHibernate

#.net #nhibernate #eager-loading #stateless-session

#.net #nhibernate #нетерпеливая загрузка #сеанс без состояния

Вопрос:

Я использую сеанс без состояния NHibernate для загрузки объемных данных в базу данных. По мере загрузки данных более поздним объектам необходимо выполнить поиск предыдущих объектов, чтобы добавить их в дочерние коллекции. Эта операция включает в себя запрос данных о дочернем объекте, которому, в свою очередь, требуется доступность коллекции правнуков.

Критерии выглядят следующим образом:

 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. похоже, они отклонили ваш патч, потому что он нарушил другой модульный тест, вы когда-нибудь получали какие-либо отзывы по этому поводу?

2. Да, Fabio также включил большую часть патча и других исправлений и улучшений для сеанса без состояния. Теперь это в NH 3.2 Beta 2.

Ответ №1:

Похоже, что это ограничение в том, как сеанс без состояния управляет контекстом временного сохранения во время двухфазной загрузки. По-видимому, в Hibernate существует исправление, которое не было перенесено на NHibernate.

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

Обновить:

Да, вышеупомянутая проблема была проблемой и в NHibernate. Я отправил исправление здесь:https://nhibernate.jira.com/browse/NH-2669