查找“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,测试通过。
posted @ 2007-05-16 10:31  生命体验之kevin-Y  阅读(6731)  评论(0编辑  收藏  举报