NHibernate LazyInitializationException .. How to prevent?

I get the following error on our 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 is not very good. The only way to get the application to work again is to reset IIS, which is not really an option. What does it mean? How can I prevent this?

+8
nhibernate
source share
4 answers

The default relationships are lazy. This means that the SQL query to load the relationship is executed only when accessing the property that contains the relationship.

The problem is that if you access a lazy property that has never been called before, when you close the session you get this error. You have solutions:

  • Do not close the session until you finish
  • Prior to closing the session, access to all lazy properties that will be used later.
+9
source share

To avoid this problem, you need to change the link for PeerGroups in the Region display class, as shown below

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

Adding Fetch.Join () will prevent a LazyInitializationException from being thrown.

+8
source share

Do not close the session until you finish working with the object.

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

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

In a WinForms application, this is a bit more complicated: you need to clearly define the boundaries of the session start and when the session is closed. In WinForms applications, I usually define "Tasks", which are some kind of Unit-Of-Work. Each task has a session. A session is created / opened when a task is created and closed when a task is completed.

In addition, you can also define some associations as non-lazy. However, if you do, you must make sure that performance is not affected.

+2
source share

In addition to the answers of Frederik and lujop, if you are working on an ASP.NET application (as suggested by your mention of the web server), it would be nice to use a dependency injection infrastructure (like Castle Windor) to handle the life cycle of your ISessions. Castle Windsor has a "PerWebRequest" lifestyle that does this for you.

Otherwise, manually create an ISession at the beginning of each request, which is destroyed (possibly automatically cleared) at the end of the request. Then your application can use this ISession.

This is definitely due to closing ISession before you think.

0
source share

Source: https://habr.com/ru/post/649945/


All Articles