Я пишу проект и использую NHibernate 3.1
SimpleTest:
IUserRepository userRepository = new UserRepository(SessionFactory);
var admin = userRepository.GetByName("admin");
admin.Profile.Signature = "Signature";
userRepository.Update(admin);
Реализация Repository.Update ():
public virtual void Update(TEntity entity)
{
if (!session.Transaction.IsActive)
{
TResult result;
using (var tx = session.BeginTransaction())
{
session.SaveOrUpdate(entity)
tx.Commit();
}
return result;
}
session.SaveOrUpdate(entity)
}
Вы не должныпутайте сессию вызова. SaveOrUpdate (entity) в ветви else, потому что это необходимо, если обновление вызывается во внешней транзакции.
- Сначала я получаю admin с
Version = 1
.Его состояние является постоянным. - Я изменяю значение любого свойства.
- Я обновляю.
Когда поток достигает строки tx.Commit();
, NHibernate генерируетзапрос:
Пользователи UPDATE SET Версия = 2, Имя = 'admin', EncryptedPassword = '21232f297a57a5a743894a0e4a801fc3', EMail = 'admin@admin.com', IsActivation = 1, IsBanned = 0, CommentsNumber = 0, CommentsNumber = 0,Role = 'Admin', FirstName = 'Alexey', LastName = 'Kovpaev', DateOfBirth = '1992-01-02T12: 00: 00.00', About = 'Just admin', Signature = 'Signature' WHERE UserId = 'e23056df-d934-4880-b6b8-f2128cd41504 'AND Version = 1
NHibernate создает исключение: NHibernate.StaleObjectStateException: строка была обновлена или удалена другой транзакцией (или сопоставление несохраненного значения было неверным)
Он также не работает и приводит к тому же исключению:
using (var tx = Session.BeginTransaction())
{
var admin = Session.CreateCriteria<User>().Add(Restrictions.Eq("Name", "admin")).UniqueResult<User>();
admin.Profile.Signature = "Signature";
Session.SaveOrUpdate(admin);
tx.Commit();
}
Во-первых, номера версий верны.Во-вторых, других транзакций просто не было.
Почему?