nHibernate не загружает свойства третьего уровня (кеширование без промывки)

Я начал переключать некоторый уже существующий код nHibernate в проекте ASP.NET на основе Sharepoint с активной загрузки и нового сеанса при каждом обращении к базе данных на ленивую загрузку и сеанс на время HTTP-запроса, и начал сталкиваться с проблемой.

Когда мы создаем элемент в этой системе, существуют отношения «многие к одному», которые заполняются раскрывающимися списками. Это дает нам идентификатор, которого достаточно для сохранения в базе данных.

Чтобы выполнить некоторые задачи после сохранения, такие как уведомление по электронной почте, мы затем загружаем тот же элемент обратно, что ранее приводило к заполнению всего дерева объектов.

Однако после перехода на ленивую загрузку и сеанс со временем жизни всего запроса мы получаем исключения NullReferenceExceptions из свойств ниже Item, которые таинственным образом имеют значение NULL.

Загружаем элемент через nHibernate в changedItem. Вызов, который терпит неудачу:

changedItem.PaperMedia.FormsAnalyst.User.Contact.Name

PaperMedia полностью заполнен, но все в FormsAnalyst имеет значение null, кроме идентификатора.

Это то же состояние, что и при его сохранении, поэтому одной из возможных причин этой проблемы является кэширование и простое извлечение элемента, поэтому nHibernate игнорирует фактические значения из базы данных. Однако я фиксирую транзакцию и явно вызываю Flush () в сеансе между сохранением и последующей загрузкой, поэтому в этом случае ни Commit (), ни Flush () не оказывают никакого влияния на кеш.

Я изменил эти свойства в соответствующих файлах hbm.xml на lazy = "false" и установил SetFetchMode FetchMode.Eager для всех, но безрезультатно.

Я также рассматривал max_fetch_depth как проблему. Если я вызываю Refresh (changedItem) в сеансе, это не имеет никакого эффекта. Однако, если я вызываю Refresh (changedItem.PaperMedia), он заполняется полностью до Name. Казалось бы, это обесценивает max_fetch_depth как проблему, но я тем не менее попытался увеличить его, установив для него значение 6 в hibernate.cfg.xml, а также SetProperty ("max_fetch_depth", "6") в экземпляре конфигурации. при создании фабрики сеансов, и это тоже не повлияло.

Не знаю, что еще попробовать.

Кто-нибудь видел что-нибудь подобное раньше? Я новичок в nHibernate, так что это может быть что-то простое ...

Изменить:

Казалось бы, проблема действительно в кешировании. Вызов Clear () в экземпляре сеанса исправляет это поведение.

Возникает вопрос, почему Flush () не обновляет кешированные элементы? Я думал, что он создан именно для этого.


person Grank    schedule 13.01.2010    source источник
comment
Является ли FormsAnalyst сгенерированным прокси-классом, когда это происходит? Я не использовал max_fetch_depth, но думаю, что это применимо только к активной загрузке.   -  person Jamie Ide    schedule 13.01.2010
comment
Да, возможно, вы правы, но на данный момент это реальный объект UserAnalyst, так как я с нетерпением загружаю его, чтобы решить проблему. Я считаю, что это был прокси-объект до того, как я начал возиться с моими файлами hbm.xml, моими режимами выборки и т. Д., Но я не нашел комбинации, которая в любом случае делает что-либо, кроме NullReferenceException.   -  person Grank    schedule 13.01.2010


Ответы (1)


Я думаю, что Flush () предназначен только для отправки изменений в базу данных ... он обновил бы кеш с указанными объектами, если бы они были в памяти в это время. Итак, вы можете использовать другой сеанс или Clear () ... или в первую очередь заполнить FormsAnalyst.

person fwalch    schedule 13.01.2010
comment
ну, в первую очередь, заполнение дочерних элементов - не лучший вариант, поскольку это новый элемент, создаваемый пользователем, поэтому мне пришлось бы отправить все эти дополнительные данные клиенту, а они отправили бы их обратно. Clear () хорошо работал в этом сценарии, но вызывал проблемы с будущей отложенной загрузкой в ​​этом сеансе после вызова Clear (). Я пока прибег к хакерскому обновлению (changedItem.PaperMedia), но все еще озадачен. Если Flush () предназначен только для отправки изменений в базу данных, никогда ли он не вернет изменения? - person Grank; 15.01.2010