开发者

NHibernate LazyInitializationException.. How to prevent?

开发者 https://www.devze.com 2023-01-30 02:10 出处:网络
I\'m getting the following error on our production web server: NHibernate.LazyInitializationException :

I'm getting the following error on our production web server:

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

which isn't good. The only way to get the application working again is to reset IIS, which isn't really an option. What does this mean? How ca开发者_开发百科n I prevent it?


To avoid this issue you need to change reference for PeerGroups in your Region mapping class as below

References(x => x.PeerGroupId, "PeerGroupId").Fetch.Join();

Adding Fetch.Join() will prevent LazyInitializationException.


Relationships by default are lazy. That means that the SQL query to load the relationship is executed only when you access the property that holds the relationship.

The problem is that if you access a lazy property, that has never been called before, with the session closed then you get that error. You have to solutions:

  • Don't close the session until you finished
  • Prior to close the session access all the lazy properties that will be used later.


Don't close the session untill you're done working with the object.

This is one of the biggest challenges of working with NHIbernate IMHO: defining the session-boundaries.

In an ASP.NET application, it is quite easy: the session starts at the beginning of the request, and you can close the session at the end of the request.

In a WinForms app, it is a bit more difficult: you'll have to clearly define the boundaries of when a session is started, and when the session is closed. In WinForms applications, I typically define 'Tasks' which represent some kind of Unit-Of-Work. Each Task has a session. The session is created / opened when a Task is created, and closed when the Task finishes.

Next to that, you can also define some associations as non-lazy. However, you should make sure that performance is not affected if you do this.


Further to Frederik and lujop's responses, if you are working on an ASP.NET app (as suggested by your mention of a web server), it's a nice idea to use a dependency injection framework (such as Castle Windor) to handle the lifecycle of your ISessions. Castle Windsor has a lifestyle setting of 'PerWebRequest' which does this for you.

Failing that, manually create an ISession at the beginning of each request which is destroyed (possibly automatically flushing itself) at the end of the request. Then your app can use this ISession.

This is definitely to do with an ISession being closed before you think it is.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号