nHibernate未加载三级属性(不可刷新缓存)

nHibernate未加载三级属性(不可刷新缓存),nhibernate,session,lazy-loading,nullreferenceexception,flush,Nhibernate,Session,Lazy Loading,Nullreferenceexception,Flush,我开始在一个基于Sharepoint的ASP.NET项目中切换一些预先存在的nHibernate代码,从每次数据库命中时的急于加载和新会话,切换到延迟加载和HTTP请求期间的会话,并开始遇到问题 当我们在这个系统中创建一个项目时,会有一些由下拉列表填充的多对一关系。这就得到了ID,它足以保存到数据库中 为了执行一些保存后任务(如电子邮件通知),我们将加载相同的项目,这将使我们填充整个对象树 然而,自从更改为延迟加载和整个请求的生存期内的会话以来,我们已经从项下神秘地为null的属性中获得了Nul

我开始在一个基于Sharepoint的ASP.NET项目中切换一些预先存在的nHibernate代码,从每次数据库命中时的急于加载和新会话,切换到延迟加载和HTTP请求期间的会话,并开始遇到问题

当我们在这个系统中创建一个项目时,会有一些由下拉列表填充的多对一关系。这就得到了ID,它足以保存到数据库中

为了执行一些保存后任务(如电子邮件通知),我们将加载相同的项目,这将使我们填充整个对象树

然而,自从更改为延迟加载和整个请求的生存期内的会话以来,我们已经从项下神秘地为null的属性中获得了NullReferenceException

我们通过nHibernate将项目加载到changedItem中。失败的呼叫是:

changedItem.PaperMedia.FormsAnalyst.User.Contact.Name
PaperMedia已完全填充,但FormsAnalyst上的所有内容都为空,ID除外

这与我们保存它时的状态相同,因此此问题的一个可能原因是缓存并简单地检索该项,因此nHibernate不知道数据库中的实际值。但是,我正在提交事务,并在保存和后续加载之间的会话上显式调用Flush(),因此如果是这种情况,Commit()和Flush()都不会对缓存产生任何影响

我已将相关hbm.xml文件中的这些属性更改为lazy=“false”,并设置了SetFetchMode FetchMode。我也渴望所有这些属性,但没有任何效果

我也在考虑最大深度。如果我在会话上调用Refresh(changedItem),它将不起作用。然而,如果我调用Refresh(changedItem.PaperMedia),它将一直填充到Name。这似乎不认为max_fetch_depth是问题所在,但我还是尝试增加它,在hibernate.cfg.xml中将它设置为6,并在创建会话工厂时在配置实例上设置SetProperty(“max_fetch_depth”,“6”),这些都没有效果

我不知道还能尝试什么

以前有人见过这样的吗?我是nHibernate的新手,所以可能很简单

编辑:

看来缓存确实是个问题。对会话实例调用Clear()可修复此行为


现在的问题是,为什么Flush()不更新缓存项?这正是我认为构建它的目的。

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

发生这种情况时,FormsAnalyst是生成的代理类吗?我没有使用max_fetch_depth,但我认为它只适用于急切加载。是的,你可能是对的,但不,这是一个实际的UserAnalyst对象,因为我急切地加载它是为了解决问题。在我开始处理我的hbm.xml文件和获取模式等之前,我相信它是一个代理对象,但我还没有找到一个组合,除了NullReferenceException之外,它还能做任何事情。好吧,首先填充子对象不是一个好的选择,因为这是用户正在创建的一个新项目,所以我必须将所有额外的数据发送到客户机,并让他们将其发送回。Clear()在该场景中工作得很好,但在调用Clear()之后,该会话的延迟加载会导致问题。我现在已经求助于黑客刷新(changedItem.PaperMedia),但仍然感到困惑。如果Flush()只用于将更改发送到数据库,它将永远无法恢复更改吗?