为什么我的ILoadEventListener没有被调用?
本文关键字:调用 我的 ILoadEventListener 为什么 | 更新日期: 2023-09-27 18:07:23
我做了一个实现ILoadEventListener
的类,并实现了一个OnLoad()
方法(当然——否则它甚至不会编译)。在创建"new NHibernate.Cfg.Configuration()"之后,我按照文档所说的添加它:
configuration.EventListeners.LoadEventListeners = new ILoadEventListener[] {
new MyListener(),
new NHibernate.Event.Default.DefaultLoadEventListener()
};
然而,它似乎从来没有被调用-我已经添加了日志语句到我的OnLoad(),并在调试器中设置了一个断点-即使在使用我的应用程序的方式,清楚地从数据库中获取对象使用这个NHibernate会话工厂。
我错过了什么?
编辑:我在源代码(NHibernate事件文档是相当稀疏)戳了一下,发现对应于IInterceptor的事件实际上是PreLoad,而不是Load,所以我试着使用它,那一个确实着火了。所以我现在可以使用它,但我仍然不知道preload/load/postload是什么
这方面的文档几乎不存在,所以这可能会帮助一些人:
任何Load事件(Load/PreLoad/PostLoad)都不会在身份缓存中的实体上触发,即使您使用Get
, Load
或再次查询。
这种类型的如果你以正确的方式斜视它是有意义的,但是由于不确定性的行为,它会造成很大的挫折,因为大多数时候,你不会知道实体是否在缓存中。显然,这些事件是指水化一个实体的过程,而不是简单地请求它。
我还没有测试过这个理论,但如果从L2缓存命中的缓存也不触发Load事件,我也不会感到惊讶,因为这些实体也不会被激活。
在实践中,这意味着如果你想让一个特定的监听器在"每个"实体上运行,你需要考虑到它最初是一个由Save
、Update
等引入会话的瞬态实例的可能性。换句话说,如果你实现了IPostLoadEventListener
,你可能也想实现IPostInsertEventListener
和IPostUpdateEventListener
。
这实际上不会改变行为-侦听器仍然只会在实体与会话关联的第一个时间运行-但至少这保证了您可以从会话中检索的每个实体都被该侦听器截获。在我的情况下,我试图使用PostLoad
向实体注入一些东西,所以这是一个可接受的解决方案。
如果你真的需要侦听器在每次检索实体时触发,你需要使用无状态会话(没有缓存)或在再次加载/查询之前驱逐实体。