我寫的項目和使用NHibernate 3.1崩潰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)
}
你一定不要混淆調用其他分支中的session.SaveOrUpdate(entity),因爲如果更新在外部事務中調用,則必須調用它。
- 首先,我收到管理員
Version = 1
。他的狀態是持久的。 - 我更改任何屬性的值。
- 我做更新。
當流量到達線
tx.Commit();
,NHibernate的生成查詢:UPDATE用戶 SET版= 2, 名稱= '管理員', EncryptedPassword = '21232f297a57a5a743894a0e4a801fc3', 使用email =「管理員@管理員.com '之間, IsActivated = 1, IsBanned = 0, CommentsNumber = 0, 角色= '管理', 姓= '阿列克謝', 名字= 'Kovpaev', DATEOFBIRTH =' 1992-01-02T12: 00:00.00', 關於= '只要管理', 簽名= '簽名' 其中userid = 'e23056df-d934-4880-b6b8-f2128cd41504' 和版本= 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();
}
首先,版本號是正確的。其次,其他交易不存在。
爲什麼?
在這段代碼中,沒有嵌套事務。並且不止一個嵌套級別,因爲它在塊「if」中被檢查。 –
我沒有正確讀取您的代碼。你明確確定沒有嵌套。好。我想知道你的UserRepository。它如何管理會話? GetByName會在內部打開和關閉一個會話,還是保持一個會話在UserRepository的生命週期中打開? – Mithon
這個代碼來自單元測試,並且有一個非常簡單的會話管理。它創建一個會話,並使用它進行所有測試。 在異常會話上升的時刻只有一個持久實體。它是管理員,具有正確的ID和版本。 –