Почему не вызывается мой ILoadEventListener? - PullRequest
1 голос
/ 31 августа 2011

Я создал класс, который реализует ILoadEventListener, и реализовал метод OnLoad() (конечно, иначе он даже не скомпилировался бы). После создания «нового NHibernate.Cfg.Configuration ()» я добавляю его , как сказано в документации :

configuration.EventListeners.LoadEventListeners = new ILoadEventListener[] {
    new MyListener(),
    new NHibernate.Event.Default.DefaultLoadEventListener()
};

Однако, кажется, его никогда не вызывают - я добавил операторы регистрации в свой OnLoad () и установил там точку останова в отладчике - даже при использовании моего приложения способом, который явно получает объекты из базы данных, используя это фабрика сессий NHibernate.

Чего мне не хватает?

РЕДАКТИРОВАТЬ: я ковырялся в исходном коде (документация события NHibernate довольно редко) и обнаружил, что событие, которое соответствует IInterceptor на самом деле PreLoad, а не Load, поэтому я попытался использовать это, и это срабатывает. Так что я могу использовать это сейчас, но я до сих пор не знаю, что такое preload / load / postload.

1 Ответ

6 голосов
/ 16 февраля 2012

Документация по этому вопросу практически отсутствует, поэтому, возможно, это поможет нескольким людям:

Ни одно из событий Load (Load / PreLoad / PostLoad) никогда не сработает на объекте, который находится в кэше идентификаторов, даже если вы Get, Load или запросите его снова.

Этот вид имеет смысл, если вы щурились на нем правильным образом, но это вызывает большое разочарование из-за недетерминированного поведения, поскольку в большинстве случаев вы не будете знать , находится ли объект в кэше. Очевидно, что эти события относятся к процессу увлажнения сущности, в отличие от простого запроса it.

Я не проверял эту теорию, но не удивлюсь, если попадания в кэш из кэша L2 также не инициируют события Load, поскольку эти объекты также не будут гидратированы.

На практике это означает, что если вы хотите, чтобы конкретный слушатель работал на «каждом» объекте, вам необходимо учитывать вероятность того, что это был первоначально временный экземпляр, который был введен в сеанс Save, Update и т. д. Другими словами, если вы реализуете IPostLoadEventListener, вы, вероятно, также захотите реализовать IPostInsertEventListener и IPostUpdateEventListener.

Это на самом деле не изменит поведение - слушатель все равно будет запускать только первый раз, когда сущность станет связанной с сеансом - но по крайней мере это гарантирует, что каждая сущность, которую вы можете извлечь из сеанс был перехвачен этим слушателем. В моем случае я пытался использовать PostLoad, чтобы ввести что-то в сущность, так что это был приемлемый обходной путь.

Если вам действительно нужно, чтобы слушатель запускал каждый каждый раз, когда извлекается сущность, вам нужно либо использовать сеанс без сохранения состояния (без кэша), либо выселять сущности перед загрузкой / запросом снова.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...