我初学Hibernate,在做下面需求是碰到错误:a different object with the same identifier value was already associated with the session: [com.retailCRM.pojo.Client#1]。不知如何解决,请大家帮帮我
需求是这样的:
有员工Employe类和客户Client类,一个员工能与多个客户联系,一个客户也可以被多个员工联系在类中体现为
class Employe:
Set<Client> clients;
class Client:
Set<Employe> employes;
两个类该属性的Hibernate映射文件分别是:
Employe.hbm.xml:
<set name="client" table="e_c_mapping" cascade="save-update" >
  <key column="employe_id"></key>
  <many-to-many class="Client" column="client_id"></many-to-many>
</set>
Client.hbm.xml:
<set name="operator" table="e_c_mapping" cascade="save-update" inverse="true">
  <key column="client_id"></key>
  <many-to-many class="Employe" column="employe_id"></many-to-many>
</set>
现在,在员工对象E1中,属性clients已经有多个Client对象,且所有Client对象中的employes结合都添加了对象E1并且都通过saveOrUpdate()方法入库。
另一个员工E2从数据库中取出,需要与E1共享一个客户C1。
我做了以下操作:
从E1对象的Client集合中(E1对象从数据库中取出)取出C1对象,添加到E2的Client集合中,在C1对象的Employe集合中添加E2对象,最后saveOrUpdate(E2)。
我使用的是Tomcat服务器,第一次(重启Tomcat后的首次操作)做该操作能成功,Hibernate记录为:
Hibernate: update employe set name=?, birthday=?, date=?, number=?, email=?, phone=?, photo=?, qq=?, sex=?, account=?, dept=? where id=?
Hibernate: update client set name=?, address=?, connecter=?, date=?, email=?, fax=?, kind=?, phone=?, state=?, web=?, zip=?, source=?, account=? where id=?
Hibernate: update employe set name=?, birthday=?, date=?, number=?, email=?, phone=?, photo=?, qq=?, sex=?, account=?, dept=? where id=?
Hibernate: update client set name=?, address=?, connecter=?, date=?, email=?, fax=?, kind=?, phone=?, state=?, web=?, zip=?, source=?, account=? where id=?
Hibernate: update client set name=?, address=?, connecter=?, date=?, email=?, fax=?, kind=?, phone=?, state=?, web=?, zip=?, source=?, account=? where id=?
Hibernate: update client set name=?, address=?, connecter=?, date=?, email=?, fax=?, kind=?, phone=?, state=?, web=?, zip=?, source=?, account=? where id=?
Hibernate: update client set name=?, address=?, connecter=?, date=?, email=?, fax=?, kind=?, phone=?, state=?, web=?, zip=?, source=?, account=? where id=?
Hibernate: update employe set name=?, birthday=?, date=?, number=?, email=?, phone=?, photo=?, qq=?, sex=?, account=?, dept=? where id=?
Hibernate: update employe set name=?, birthday=?, date=?, number=?, email=?, phone=?, photo=?, qq=?, sex=?, account=?, dept=? where id=?
Hibernate: update employe set name=?, birthday=?, date=?, number=?, email=?, phone=?, photo=?, qq=?, sex=?, account=?, dept=? where id=?
Hibernate: insert into e_c_mapping (employe_id, client_id) values (?, ?)但是第二次我要把C2客户共享给E2时,就出现a different object with the same identifier value was already associated with the session: [com.retailCRM.pojo.Client#1]错误

解决方案 »

  1.   

    哦,映射文件中SET标签中的name属性没有错,是我在工程中的命名,这里直接贴过来的。
      

  2.   

    中间表在这里:set 标签中的 table属性
    table="e_c_mapping" 
    接口中就是使用的saveOrUpdate()方法。下面是借口中的实现方法:
             public Session session=null;
    public Transaction tx=null;
    public void saveOrUpdate(T obj) throws DatabaseOperatException {
    try {
    session=getSession();
    tx=session.beginTransaction();
    session.saveOrUpdate(obj);
    tx.commit();
    } catch (HibernateException e) {
    tx.rollback();
    e.printStackTrace();
    throw new DatabaseOperatException("db operate exception!");
    }finally{
    closeSession();
    }
    }开始我以为是session这个全局变量的问题。但是我定义在方法里面也还是有错误。
      

  3.   

     当出现a different object with the same identifier value was already associated with the session时,一般是因为在hibernate中同一个session里面有了两个相同标识但是是不同实体。       有如下几种解决方案:(1)使用session.clean(),如果在clean操作后面又进行了saveOrUpdate(object)等改变数据状态的操作,有可能会报出"Found two representations of same collection"异常。(2)使用session.refresh(object),当object不是数据库中已有数据的对象的时候,不能使用session.refresh(object)因为该方法是从hibernate的session中去重新取object,如果session中没有这个对象,则会报错所以当你使用saveOrUpdate(object)之前还需要判断一下。(3)session.merge(object),Hibernate里面自带的方法,推荐使用。
      

  4.   


    这一段我在网上查到过,都不能解决问题。问题解决了,是映射文件有问题。就是员工的级联操作那,吧save-update改成update就可以了。
    从需求上来说,确实是不需要级联保存,因为我的系统中员工录入时是不负责任何客户的。
    但是具体原理是是因为什么,希望达人帮我解答。