Сессия NHibernate / Транзакции - PullRequest
1 голос
/ 13 марта 2012

Я пытаюсь использовать шаблон сеанса для запроса, и у меня возникают проблемы с получением записи сразу после ее сохранения.Причина этого в том, что мне нужно получить записи, к которым относятся внешние ключи.

Некоторый (упрощенный) код:

    // UnitOfWork Attribute

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        SessionFactory.Begin();
    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        if (filterContext.Exception == null) {
            try {
                SessionFactory.Commit();
            } catch {
                SessionFactory.Rollback();
                throw;
            }
        } else {
            SessionFactory.Rollback();
            throw filterContext.Exception;
        }
    }

    // Service layer

    public void Save(Form form)
    {
        _repository.Save(form);

        var savedForm = _repository.Get(form.Id);
        SendEmail(savedForm);
    }

    // Repository

    public void Save(Form form)
    {
        var session = SessionFactory.CurrentSession;

        session.SaveOrUpdate(form);
    }

Проблема в том, что когда я пытаюсь получитьзапись, транзакция еще не была зафиксирована, поэтому она просто дает мне то, что уже находится в сеансе.Мне просто нужно будет зафиксировать транзакцию после сохранения и открыть новую транзакцию для ее получения?

Спасибо

Обновление:

IВнедрили Agathas Storefront способ действий, предоставляющий сервисному уровню контроль над транзакциями, а именно:

public class UnitOfWork : IUnitOfWork
{
    public void Commit()
    {
        var session = SessionFactory.CurrentSession;

        using (ITransaction transaction = session.BeginTransaction())
        {
            try { 
                transaction.Commit(); 
            } catch {
                transaction.Rollback();
                throw;
            }
        }
    }


    public void Clear()
    {
        var session = SessionFactory.CurrentSession;

        session.Clear();
    }
}

Затем на сервисном уровне:

public void SaveForm(Form form)
{
    _repository.Save(form);

    _uow.Commit();
    _uow.Clear();

    var savedForm = _repository.Get(form.Id);
    SendEmail(savedForm);
}

Обновление2

ОК, думаю, я нашел подходящее решение.Я вернулся к шаблону транзакции на запрос, и после сохранения формы я теперь сбрасываю ее, а затем вытесняю форму из сеанса, чтобы заставить NH получить ее из БД.

// Service layer
public void SaveForm(Form form)
{
    _repository.Save(form);

    var savedForm = _repository.Get(form.Id);
    SendEmail(savedForm);
}

// Repository

public void Save(Form form)
{
    var session = SessionFactory.CurrentSession;

    session.SaveOrUpdate(form);
    session.Flush();
    session.Evict(form);
}

Ответы [ 2 ]

1 голос
/ 13 марта 2012

Один из вариантов: измените свою стратегию идентификатора с идентификатора, созданного в базе данных, на тот, который управляется NHibernate (см. Параметры в http://nhibernate.info/doc/nh/en/index.html#mapping-declaration-id-generator), или другой вариант, измените режим сброса вашего сеанса на FlushMode.Auto.

1 голос
/ 13 марта 2012

Пока вы не очистите сеанс или не уменьшите объем транзакции, у вас не будет идентификатора, потому что nhibernate не вставит запись.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...