0

我开始在基于 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() 不会更新缓存的项目?这正是我认为它的目的。

4

1 回答 1

0

我认为 Flush() 仅用于将更改发送到数据库...如果此时它们在内存中,它将使用引用的对象更新缓存。因此,您可以使用另一个会话或 Clear()... 或首先填充 FormsAnalyst。

于 2010-01-13T21:48:41.450 回答