NHibernate: "failed to lazy initialize ...", DDD approach

I am trying to set up NHibernate in an ASP.NET MVC application using a DDD approach. However, I get an error when I try to lazy load an object linked to objects. This is how I structured my application:

Infrastructure layer: Contains the mapping files, repository implementations, and the NHibernate loader for setting up and building the factory session.

Here's an example of a repository:

public class CustomerRepository : ICustomerRepository
{
    public Customer GetCustomerById(int customerId)
    {
        using (var session = NHibernateBootstrapper.OpenSession())
            return session.Get<Customer>(customerId);
    }
}

      

Domain Level: Has simple POCO classes, repository and service interfaces.

Application layer: Contains service implementations.

Here's an example of a service:

public class CustomerService : ICustomerService
{
    private ICustomerRepository _repository;

    public CustomerService(ICustomerRepository repository)
    {
        _repository = repository;
    }

    public Customer GetCustomerById(int customerId)
    {
        return _repository.GetCustomerById(customerId);
    }
}

      

Presentation tier : Contains an ASP.NET MVC application. And this is where I found my problem. Using the MVC approach, I have a controller that, using the CustomerService, gets the customer and displays the customer in a (strongly typed) view. This customer has an associated Contact object, and when I try to access it in my view using Model.Contact where Model is a Customer object, I get a LazyInitializationException.

I know why I understand this. This is because the session used to fetch the Customer into the CustomerRepository is already dead. My problem is how can I fix this. I would like if I could avoid getting the associated Contact object for the Client in my repository, because some views only need the Client data and not the Contact data. If this is possible at all?

So, to the question: is it possible to wait for a database request until the associated object is needed at the presentation layer?

I think I need something like this article . I just can't figure out how to implement it in the infrastructure layer or where should it be implemented?

Thanks in advance. Any help would be much appreciated!

+2


source to share


3 answers


As far as session management is concerned, typically one session is used for each request. You can see an example implementation here . It is an open source project that was designed to install new asp.net applications using Nhibernate easily. the source code can be based here .



Hope it helps.

+2


source


I also recommend Sharp Architecture.

Another approach, as well as a suggestion, is to avoid passing entities to views. There are other issues besides session management - business rules flowing in kind, bloated / spagetti code, etc. Use the ViewModel approach.



Another problem you will get is keeping your entities in session. As soon as you try to get your client from session ["client"], you will get the same exception. There are several solutions for this, such as storing IDs or adding repository methods to prevent lazy loading of the objects you intend to store in the session - read NHibernate SetFetchMode - which of course can be used to pass the object to Views. But as I said, it's better to stick with the ViewModel approach. Google for the ViewModel or refer to the ASP.NET MVC In Action book which uses code samples from http://code.google.com/p/codecampserver/ . Also read this for example.

+1


source


Are all your properties and methods in your Customer class labeled virtual

?

How do you open and close a session? I use ActionFilterAttribute

called TransactionPerRequest

and decorate it with all my controllers.

Check this one for implementation.

0


source







All Articles