查找“a different object with the same identifier value was already....”的原因
在做一下数据转换的程序时,部分对象更新会出现以下异常:
a different object with the same identifier value was already associated with the session: 162, of class: Mag.Entity.Transaction
at NHibernate.Impl.SessionImpl.CheckUniqueness(Key key, Object obj)
at NHibernate.Impl.SessionImpl.DoUpdateMutable(Object obj, Object id, IClassPersister persister)
at NHibernate.Impl.SessionImpl.DoUpdate(Object obj, Object id, IClassPersister persister)
at NHibernate.Impl.SessionImpl.Update(Object obj)
at Mag.DbConnect.ConnectSession.Update(Object obj) in d:\magazine_v3\mag.dbconnect\connectsession.cs:line 74
at Mag.Window.DbExchangeApp.Form1.getExchange4_1() in d:\magazine_v3\mag.window.dbexchangeapp\form1.cs:line 561
在网上查询,.net的很少信息,那就看java的,在这看到一些代码
http://forum.springframework.org/showthread.php?t=27235
为了找到根源,我需要把这种异常模拟出来,上面的代码给了一些提示。
1.是不是一个连接当中只能有一个对象处于有效状态了?
Entity.Locator.IssueLocator isuLoc = new IssueLocator(conn);
Entity.Locator.TransactionLocator tranLoc = new TransactionLocator(conn);
Entity.Issue isu = isuLoc.SelectOne(isbn);
Entity.Transaction tran1 = tranLoc.SelectOne(isu);
Entity.Transaction tran2 = tranLoc.SelectOne(isu);

conn.Update(tran1);
conn.Update(tran2);
上面的代码并没引起上面的错误,测试是通过的。不过有意思是,没有update语句!哦,是不是没的提交命令呢?于是把代码改为
conn.BeginTransaction();//conn是一个封闭了ISession的类
conn.Update(tran1);
conn.Update(tran2);
conn.CommitTransaction();
还是没有update语句,稍修改一个tran1、tran2某个属性的值,update语句出现了,可只有一条!!tran1的更新被忽略了,聪明!
2.是不是我们自己构造的对象不能用于更新呢?
把程序中使用的属性拷贝的方法也放到测试中
private void copyObject(object objSource,object objDest)
{
Type destType = objDest.GetType();

Type type = objSource.GetType();
System.Reflection.PropertyInfo [] properties = type.GetProperties();
for(int i=0;i<properties.Length;i++)
{
if(!properties[i].CanWrite)
continue;
object objVal = properties[i].GetValue(objSource,null);
if(objVal==null)
continue;
properties[i].SetValue(objDest,objVal,null);
}
}
测试的代码改为
Entity.Transaction tran1 = tranLoc.SelectOne(isu);
Entity.Transaction tran2 = new Transaction();
this.copyObject(tran1,tran2);
tran1.Memo = tran1.Memo + "测试。";
tran2.Memo = tran2.Memo + "测试。";
conn.BeginTransaction();
// conn.Update(tran1);
conn.Update(tran2);
conn.CommitTransaction();
异常如期出现了,高兴,找到了
NHibernate.NonUniqueObjectException : a different object with the same identifier value was already associated with the session: 4583, of class: Mag.Entity.Transaction
再尝试只更新tran1,测试通过。
a different object with the same identifier value was already associated with the session: 162, of class: Mag.Entity.Transaction
at NHibernate.Impl.SessionImpl.CheckUniqueness(Key key, Object obj)
at NHibernate.Impl.SessionImpl.DoUpdateMutable(Object obj, Object id, IClassPersister persister)
at NHibernate.Impl.SessionImpl.DoUpdate(Object obj, Object id, IClassPersister persister)
at NHibernate.Impl.SessionImpl.Update(Object obj)
at Mag.DbConnect.ConnectSession.Update(Object obj) in d:\magazine_v3\mag.dbconnect\connectsession.cs:line 74
at Mag.Window.DbExchangeApp.Form1.getExchange4_1() in d:\magazine_v3\mag.window.dbexchangeapp\form1.cs:line 561在网上查询,.net的很少信息,那就看java的,在这看到一些代码
http://forum.springframework.org/showthread.php?t=27235
为了找到根源,我需要把这种异常模拟出来,上面的代码给了一些提示。
1.是不是一个连接当中只能有一个对象处于有效状态了?
Entity.Locator.IssueLocator isuLoc = new IssueLocator(conn);
Entity.Locator.TransactionLocator tranLoc = new TransactionLocator(conn);
Entity.Issue isu = isuLoc.SelectOne(isbn);
Entity.Transaction tran1 = tranLoc.SelectOne(isu);
Entity.Transaction tran2 = tranLoc.SelectOne(isu); 
conn.Update(tran1);
conn.Update(tran2);
conn.BeginTransaction();//conn是一个封闭了ISession的类
conn.Update(tran1);
conn.Update(tran2);
conn.CommitTransaction();
2.是不是我们自己构造的对象不能用于更新呢?
把程序中使用的属性拷贝的方法也放到测试中
private void copyObject(object objSource,object objDest)
{
Type destType = objDest.GetType();
Type type = objSource.GetType();
System.Reflection.PropertyInfo [] properties = type.GetProperties();
for(int i=0;i<properties.Length;i++)
{
if(!properties[i].CanWrite)
continue;
object objVal = properties[i].GetValue(objSource,null);
if(objVal==null)
continue;
properties[i].SetValue(objDest,objVal,null);
}
}
Entity.Transaction tran1 = tranLoc.SelectOne(isu);
Entity.Transaction tran2 = new Transaction();
this.copyObject(tran1,tran2);
tran1.Memo = tran1.Memo + "测试。";
tran2.Memo = tran2.Memo + "测试。";
conn.BeginTransaction();
// conn.Update(tran1);
conn.Update(tran2);
conn.CommitTransaction();
NHibernate.NonUniqueObjectException : a different object with the same identifier value was already associated with the session: 4583, of class: Mag.Entity.Transaction



浙公网安备 33010602011771号