I am writing project and using NHibernate 3.1
SimpleTest:
IUserRepository userRepository = new UserRepository(SessionFactory);
var admin = userRepository.GetByName("admin");
admin.Profile.Signature = "Signature";
userRepository.Update(admin);
Implementation 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)
}
You must not confuse the call session.SaveOrUpdate (entity) in the branch else, because it is necessary if the Update called in an external transaction.
- First, I receive admin with
Version = 1
. His state is persistent. - I change the value of any property.
- I do update.
When the flow reaches the line
tx.Commit();
, NHibernate generates a query:UPDATE Users SET Version = 2, Name = 'admin', EncryptedPassword = '21232f297a57a5a743894a0e4a801fc3', EMail = 'admin@admin.com', IsActivated = 1, IsBanned = 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 throws an exception: NHibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)
It also does not work and leads to the same exception:
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();
}
First, the version numbers are correct. Second, other transactions just did not exist.
Why?