我在生产网络服务器上收到以下错误:
NHibernate.LazyInitializationException
:
Initializing[Domain.Entities.AudienceTypes.Region#4]-failed to lazily initialize a
collection of role: Domain.Entities.AudienceTypes.Region.PeerGroups,
no session or session was closed
这不好。让应用程序再次运行的唯一方法是重置IIS,这不是一个真正的选择。这是什么意思?我该如何预防?
答案 0 :(得分:10)
要避免此问题,您需要在Region映射类中更改PeerGroups的引用,如下所示
References(x => x.PeerGroupId, "PeerGroupId").Fetch.Join();
添加 Fetch.Join()会阻止LazyInitializationException。
答案 1 :(得分:9)
默认情况下,关系是懒惰的。这意味着只有在访问保存关系的属性时才会执行加载关系的SQL查询。
问题在于,如果您访问之前从未调用过的惰性属性,并且会话已关闭,那么您将收到该错误。 你需要解决方案:
答案 2 :(得分:2)
请勿关闭会话,直到您使用该对象为止。
这是与NHIbernate IMHO合作的最大挑战之一:定义会话边界。
在ASP.NET应用程序中,它非常简单:会话在请求开始时开始,您可以在请求结束时关闭会话。
在WinForms应用程序中,它有点困难:您必须清楚地定义会话何时开始以及会话何时关闭的界限。 在WinForms应用程序中,我通常定义代表某种工作单元的“任务”。每个任务都有一个会话。在创建任务时创建/打开会话,在任务完成时关闭会话。
接下来,您还可以将某些关联定义为非惰性。但是,如果执行此操作,则应确保性能不受影响。
答案 3 :(得分:0)
除了Frederik和lujop的回复之外,如果您正在开发一个ASP.NET应用程序(如您提到的Web服务器所建议的那样),那么使用依赖注入框架(例如Castle Windor)来处理它是一个不错的主意你的ISessions的生命周期。 Castle Windsor拥有'PerWebRequest'的生活方式,为您提供此服务。
如果失败,请在每个请求开始时手动创建一个ISession,该请求在请求结束时被销毁(可能会自动刷新)。然后你的应用可以使用这个ISession。
这绝对与你想到之前关闭的ISession有关。