nHibernate没有加载第三级属性(不可刷新的缓存)

时间:2010-01-13 18:03:43

标签: nhibernate session lazy-loading nullreferenceexception flush

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

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

为了执行一些保存后的任务,例如电子邮件通知,我们会重新加载相同的项目,之前会让我们填充整个对象树。

但是,由于更改为延迟加载和具有整个请求生命周期的会话,我们一直从Item下面的属性中获取NullReferenceExceptions,这些属性神秘地为null。

我们通过nHibernate将项加载到changedItem中。失败的电话是:

changedItem.PaperMedia.FormsAnalyst.User.Contact.Name

PaperMedia已完全填充,但FormsAnalyst上的所有内容均为空,除了ID。

这与我们保存时的状态相同,因此导致此问题的一个可能原因是项被缓存并简单检索,因此nHibernate不知道数据库中的实际值。但是,我提交了事务,并在会话中显式调用了Flush(),在save和后续加载之间,所以如果是这种情况,则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”)设置为6在创建会话工厂时,这些也没有任何效果。

我不知道还有什么可以尝试的。

之前有人见过类似的东西吗?我是nHibernate的新手,所以它可能很简单......

修改

似乎缓存确实是问题所在。在会话实例上调用Clear()可以修复此行为。

所以问题现在变成了,为什么Flush()不会更新缓存的项目?这正是我认为它的目的。

1 个答案:

答案 0 :(得分:0)

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