NHibernate does not update entity when repository is passed by constructor

Posted by Alex on Stack Overflow See other posts from Stack Overflow or by Alex
Published on 2010-05-14T21:40:51Z Indexed on 2010/05/14 21:44 UTC
Read the original article Hit count: 206

Hi everybody,

I am developing with NHibernate for the first time in conjunction with ASP.NET MVC and StructureMap. The CodeCampServer serves as a great example for me. I really like the different concepts which were implemented there and I can learn a lot from it.

In my controllers I use Constructur Dependency Injection to get an instance of the specific repository needed.

My problem is: If I change an attribute of the customer the customer's data is not updated in the database, although Commit() is called on the transaction object (by a HttpModule).

public class AccountsController : Controller
{
    private readonly ICustomerRepository repository;

    public AccountsController(ICustomerRepository repository)
    {
        this.repository = repository;
    }

    public ActionResult Save(Customer customer)
    {
        Customer customerToUpdate = repository
            .GetById(customer.Id);

        customerToUpdate.GivenName = "test"; //<-- customer does not get updated in database
        return View();      
    }
}

On the other hand this is working:

public class AccountsController : Controller
{
    [LoadCurrentCustomer]
    public ActionResult Save(Customer customer)
    {
        customer.GivenName = "test"; //<-- Customer gets updated
        return View();              
    }
}

public class LoadCurrentCustomer : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        const string parameterName = "Customer";

        if (filterContext.ActionParameters.ContainsKey(parameterName))
        {
            if (filterContext.HttpContext.User.Identity.IsAuthenticated)
            {                    
                Customer CurrentCustomer = DependencyResolverFactory
                    .GetDefault()
                    .Resolve<IUserSession>()
                    .GetCurrentUser();

                filterContext.ActionParameters[parameterName] = CurrentCustomer;
            }
        }

        base.OnActionExecuting(filterContext);
    }
}

public class UserSession : IUserSession
{
    private readonly ICustomerRepository repository;

    public UserSession(ICustomerRepository customerRepository)
    {
        repository = customerRepository;
    }

    public Customer GetCurrentUser()
    {
        var identity = HttpContext.Current.User.Identity;

        if (!identity.IsAuthenticated)
        {
            return null;
        }

        Customer customer = repository.GetByEmailAddress(identity.Name);
        return customer;
    }
}

I also tried to call update on the repository like the following code shows. But this leads to an NHibernateException which says "Illegal attempt to associate a collection with two open sessions". Actually there is only one.

public ActionResult Save(Customer customer)
{
    Customer customerToUpdate = repository
        .GetById(customer.Id);

    customer.GivenName = "test";
    repository.Update(customerToUpdate);

    return View();  
}

Does somebody have an idea why the customer is not updated in the first example but is updated in the second example? Why does NHibernate say that there are two open sessions?

© Stack Overflow or respective owner

Related posts about asp.net-mvc

Related posts about nhibernate