我开始在基于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()不会更新缓存的项目?这正是我认为它的目的。
答案 0 :(得分:0)
我认为Flush()仅用于向数据库发送更改...如果它们在内存中,它将使用引用的对象更新缓存。因此,您可以使用另一个会话或Clear()...或首先填充FormsAnalyst。