views:

50

answers:

3

I am getting this exception when I attempt to access an object that is stored in a property of my domain object. I have done some research and still do not understand why I am getting this error.

I have a very basic repository in which I am creating a session and then using a ICriteria query to fetch the first record from the list of results. My Connection domain object has one to many relationship mapped to Server. Why does the session not include the server as a proxy when it fetches the Connection object? I'm not very familiar session managment with NHibernate.

Here is my implementation:

Domain obj:

public class Connection {

public virtual int Id { get; private set; }


public virtual string FullName { get; set; }


public virtual string Email { get; set; }


public virtual string NickName { get; set; }


public virtual string Alternative { get; set; }


public virtual bool IsInvisible { get; set; }


public virtual Server CurrentServer { get; set; }

}

  public Connection GetConnection()
    {
        using (ISession session = NHibernateHelper.OpenSession())
        {
            ICriteria crit = session.CreateCriteria(typeof(Connection));
            crit.SetMaxResults(1);
            IList<Connection> connection = crit.List<Connection>();
            return connection[0];

        }
    }

The above will successfully return a Connection object. However accessing the CurrentServer property with throw the exception. It is/was my assumption that NHibernate was aware of the relationship that this object has with 'CurrentServer' and would therefore load that object, lazily, when requested. Can someone tell me where I was led astray?

Thanks!

+1  A: 

You dispose the session first, and start the lazy loading after that. An object should be connected to a session to enable lazy loading.

Paco
Wrapping your session in a using statement eliminates the possibility of lazy loading.
Jamie Ide
@Jamie How does one dispose of a session properly while still facilitating lazy loading?
Nick
@Nick You can manually dispose a session by calling the dispose method of course. The easiest way to use a session is creating one session and one transaction per "action of a user". Action of a user is defined in a different way for the type of application you build (web, winforms, wpf, service, etc.). I think it is possible to wrap a session in a using statement (I ever tried), but not with a simple architecture.
Paco
@Nick -- If it's a web app., use the session-per-request pattern. If it's a Windows app. it will take more work. I hold a session open for the lifetime of a Windows Form and dispose it in the FormClosing event. This works great for all but a few cases.
Jamie Ide
Thank you both. I did some research on different architectures out there to solve my problem. I think you are both describing a 'Unit Of Work' pattern. This is the solution I used http://nhforge.org/wikis/patternsandpractices/nhibernate-and-the-unit-of-work-pattern.aspx
Nick
@Jamie Ide - Ultimately you answered my question concerning the session and lazy loading. If you add an answer to this thread I would gladly mark it as the 'golden' answer. Thanks again.
Nick
A: 

I found the answer due to Jamie Ide's comment. The problem was that I was wrapping my session in a using statement. That meant that when I attempted to access the Server property the current session had already been disposed and therefore the lazy loading could not use that session to fetch the server.

Nick
A: 

If it's a web app., use the session-per-request pattern. If it's a Windows app. it will take more work. I hold a session open for the lifetime of a Windows Form and dispose it in the FormClosing event. This works great for all but a few cases.

What won't I do for 15 points? :-)

Jamie Ide
Hey might as well collect :) Thanks again for the insight.
Nick