Я пытаюсь вставить в таблицу столбец Identity Id, но получаю исключение;
NHibernate.AssertionFailure: нулевой идентификатор в записи APP.Domain.Entity.EntityName (не сбрасывать сеанс после возникновения исключения)
Я использовал session.Flush()
как в точке фиксации, так и в точке отката транзакции, и после этого все, казалось, работало ненадолго, затем исключение снова запустилось.
using (var tranx = _session.BeginTransaction())
{
try
{
Entity entityName = new Entity();
entityName.propert1 = propert1.value;
entityName.propert2 = propert2.value;
entityName.propert3 = propert3.value;
entityName.propert4 = propert4.value;
_session.Save(entityName);
.....
other transactions
.....
tranx.Commit();
_session.Flush();
}
catch (Exception ex)
{
tranx.Rollback();
_session.Flush();
}
}
Я ожидаю, что в таблицу БД будет вставлена запись и автоматически сгенерирован идентификатор для нее, но вместо этого я получаю журнал;
Всего 1 ответ
Ниже код в вашем вопросе:
_session.Save(entityName);
.....
other transactions
.....
tranx.Commit();
_session.Flush();
похоже, что вы делаете несколько действий в одной транзакции - ОК; это называется Единица работы.
Затем в блоке catch
вы откатываете транзакцию (отменяете UoW), как показано ниже:
catch (Exception ex)
{
tranx.Rollback();//<--This is OK
_session.Flush();//<--Why this? Remove this line.
}
Это тоже нормально. Но тогда вы ISession
. Почему так?
Ваш использующий блок правильно расположит сеанс. Я не вижу никакого преимущества сброса сессии в блоке catch
. Вы должны удалить эту строку.
Исключение, которое вы упомянули в вопросе:
NHibernate.AssertionFailure: нулевой идентификатор в записи APP.Domain.Entity.EntityName (не сбрасывать сеанс после возникновения исключения)
не является настоящим исключением. До этого произошло настоящее исключение. Вы используете исключение в блоке catch
. Лучшим способом является модификация блока блока catch
для обработки (регистрировать может быть исключение и повторно генерировать (с помощью throw;
исходное исключение)) исключение. Если вы не можете обработать исключение, просто удалите блоки try-catch
и оставьте исключение снаружи; вызывающий должен справиться с этим. Ваш блокирующий блок в любом случае ISession
- он также откатит транзакцию, если не зафиксирован.
Я ожидаю, что запись будет вставлена в таблицу БД и автоматически сгенерирован идентификатор для нее, но вместо этого я получаю журнал
Как я уже говорил выше, ваше настоящее исключение потребляется в молчании. Поэтому мы не можем сказать вам, почему этого не происходит. Осуществите меры, упомянутые выше, и вы сами узнаете причину.
Почему не Flush
после исключения NHibernate?
Unit Of Work - очень сложная система. Он отслеживает изменения для всех загруженных объектов. NHibernate делает отличные вещи, чтобы сохранить это в памяти копий объектов в соответствии с основной СУБД. Flush
(или другие способы автоматической очистки) обновит RDBMS с изменениями в памяти. Когда выдается исключение NHibernate, это не гарантирует, что это состояние больше не находится в согласованном состоянии. Именно поэтому NHibernate рекомендует избавиться от сессии и начать с нуля.