NHibernate не обновляет объект, когда репозиторий передается конструктором

Я впервые разрабатываю NHibernate в сочетании с ASP.NET MVC и StructureMap. Отличным примером для меня служит CodeCampServer. Мне очень нравятся различные концепции, которые были реализованы там, и я могу многому у них научиться.

В своих контроллерах я использую Constructur Dependency Injection, чтобы получить экземпляр нужного репозитория.

Моя проблема: если я изменяю атрибут клиента, данные клиента не обновляются в базе данных, хотя Commit() вызывается для объекта транзакции (с помощью 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();      
    }
}

С другой стороны, это работает:

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;
    }
}

Я также попытался вызвать обновление в репозитории, как показано в следующем коде. Но это приводит к исключению NHibernateException, в котором говорится: «Незаконная попытка связать коллекцию с двумя открытыми сеансами». На самом деле есть только один.

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

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

    return View();  
}

У кого-нибудь есть идея, почему клиент не обновляется в первом примере, но обновляется во втором примере? Почему NHibernate говорит, что есть две открытые сессии?


person Alex    schedule 14.05.2010    source источник


Ответы (2)


попробуйте вызвать репозиторий.Flush()

person Al W    schedule 14.05.2010

Наконец я нашел проблему. Когда я получал клиента по его идентификатору, я всегда открывал новый сеанс вместо использования сеанса в рамках запроса.

Тем не менее, большое спасибо за вашу помощь!

person Alebo    schedule 16.05.2010