我开始在基于 Sharepoint 的 ASP.NET 项目中将一些预先存在的 nHibernate 代码从急切加载和每个数据库命中的新会话切换到延迟加载和 HTTP 请求期间的会话,然后开始遇到问题。
当我们在这个系统中创建一个项目时,有一些由下拉列表填充的多对一关系。这为我们提供了 ID,这足以保存到数据库中。
为了执行一些保存后的任务,比如电子邮件通知,我们然后加载相同的项目,这之前会让我们填充整个对象树。
但是,自从更改为延迟加载和具有整个请求生命周期的会话以来,我们一直在从 Item 下面的属性中获取 NullReferenceExceptions,这些属性神秘地为空。
我们通过 nHibernate 将 item 加载到 changedItem 中。失败的电话是:
changedItem.PaperMedia.FormsAnalyst.User.Contact.Name
PaperMedia 已完全填充,但 FormsAnalyst 上的所有内容都为空,除了 ID。
这与我们保存它时的状态相同,因此导致此问题的一个可能原因是 Item 被缓存并简单地检索,因此 nHibernate 不知道数据库中的实际值。但是,我正在提交事务,并在保存和后续加载之间在会话上显式调用 Flush(),所以如果是这种情况,那么 Commit() 和 Flush() 都不会对缓存产生任何影响。
我已将相关 hbm.xml 文件中的这些属性更改为lazy="false",并为所有这些属性设置了 SetFetchMode FetchMode.Eager,但没有任何效果。
我也在考虑将 max_fetch_depth 作为问题。如果我在会话上调用 Refresh(changedItem),它没有效果。但是,如果我调用 Refresh(changedItem.PaperMedia),它将一直填充到 Name。这似乎将 max_fetch_depth 视为问题,但我仍然尝试增加它,将其设置为 hibernate.cfg.xml 中的 6 以及配置实例上的 SetProperty("max_fetch_depth", "6")在创建会话工厂时,这些也没有效果。
我不知道还能尝试什么。
以前有人见过这样的事情吗?我是 nHibernate 的新手,所以它可能很简单......
编辑:
看来缓存确实是问题所在。在会话实例上调用 Clear() 可修复此行为。
所以现在的问题变成了,为什么 Flush() 不会更新缓存的项目?这正是我认为它的目的。