I have this three classes: User, Person and Question. The relations between them is as follows:
Class User has a property Person (one to one, outer join)
Class Person has a property User (one to one, outer join) and a property Questions (Iesi.ISet of Question) (many to one, lazy)
Class Question has a property Person (one to many, Class Person is lazy)
When a User logs into the web site, the instance is saved in a session variable (Session["LoggedUser"]).
I use the Open-Session-In-View Patter, which means that a NHibernate session is open at the beggining of the web request, and it is closed at the en of the request (that is, when the page is sent back to the user's browser). So the same session is used everywhere in a request. Of course, as the User is saved in the session variable, everytime I have to use it I have to reattach it to the NHibernate session:
Code:
User rUser = (User)Session["LoggedUser"];
session.Lock(rUser, LockMode.None);
The problem appears when I try to reach Person's collection of Question
Code:
foreach (Question questionAsked in rUser.Person.Questions)
throws an exception:
"Failed to lazily initialize a collection - no session"
All this code is followed side by side, there's no extra code between them, so... how could it say there's no Session?
Now... if I where to do this:
Code:
Person rPerson = ((User)Session["LoggedUser"]).Person;
session.Lock(rPerson, LockMode.None);
foreach (Question questionAsked in rPerson.Questions)
it
usually works fine, although some unexplainable times it throws this exception:
"Could not initialize proxy - the owning Session was closed."
Can anyone explain to me why the first error happens?
Can anyone explain to me why the SECOND error happens?
Alejandro.
ADDED:
For mor information, I add here the log entries:
If Person is locked
NHibernate.Impl.SessionImpl [(null)] <(null)> - opened session
NHibernate.Engine.Cascades [(null)] <(null)> - unsaved-value: 0
NHibernate.Impl.SessionImpl [(null)] <(null)> - reassociating transient instance: [Rules.Person#5]
NHibernate.Engine.Cascades [(null)] <(null)> - processing cascades for: Rules.Person
NHibernate.Engine.Cascades [(null)] <(null)> - cascading to collection: Rules.Person.Questions
NHibernate.Engine.Cascades [(null)] <(null)> - cascading to lock()
NHibernate.Engine.Cascades [(null)] <(null)> - unsaved-value: 0
NHibernate.Impl.SessionImpl [(null)] <(null)> - reassociating transient instance: [Rules.Question#12]
NHibernate.Engine.Cascades [(null)] <(null)> - cascading to lock()
NHibernate.Engine.Cascades [(null)] <(null)> - unsaved-value: 0
NHibernate.Impl.SessionImpl [(null)] <(null)> - reassociating transient instance: [Rules.Question#14]
...(more locking for the rest of the Questions)
NHibernate.Engine.Cascades [(null)] <(null)> - cascading to lock()
NHibernate.Engine.Cascades [(null)] <(null)> - unsaved-value: 0
NHibernate.Impl.SessionImpl [(null)] <(null)> - reassociating transient instance: [Rules.User#20]
NHibernate.Engine.Cascades [(null)] <(null)> - done processing cascades for: Rules.Person
NHibernate.Impl.SessionImpl [(null)] <(null)> - closing session
Now,
if User is locked:
NHibernate.Impl.SessionImpl [(null)] <(null)> - reassociating transient instance: [Rules.User#20]
ERROR NHibernate.LazyInitializationException [(null)] <(null)> - Failed to lazily initialize a collection - no session
NHibernate.LazyInitializationException: Failed to lazily initialize a collection - no session
NHibernate.Impl.SessionImpl [(null)] <(null)> - closing session