hibernate's NonUniqueObjectException error handling

 

Specific description: A different object with the same identifier value was already associated... problem handling 

Online explanation: 

Hibernate's session caches previously processed data, such as querying certain information such as User objects, and when querying for the second time, it can be retrieved from the cache. It is precisely because of the existence of the cache in the session that there will be problems when it is not handled properly. For example the following scenario: 

  1. A User object is found, and the id is 1. At this time, the user creates a new user with an id of 1 (the id is the user's primary key). Performing the save operation will cause a NonUniqueObjectException exception, because the primary key value is the same, but the referenced object different.

  2. There may also be such a problem in the process of performing the update, as in the following program (from the Internet, not verified):

      class A{}  

class B{  

     private A many_to_one_A;  

  

public void update_A_B(A a) {  

    B b=findByA(a);  

    update(b);  

    update(a);  

 

Reason for the error: The incoming A is an independent entity. After loading B , the b object will load an a in this session , so when update(a) , the session is reloaded and updated , and so on. 

Solution:  

public void update_A_B(A a) {  

    B b=findByA(a);  

    update(b);  

    a=b.getMany_to_one_A();  

    update(a);  

  

In addition, the solution is also given on the Internet:

  1. session.evict(objPO); or session.clear(); before update , clear the cache, or call the evict method to set the current object to the detached state

  2. Use session 's merge method, but this method may be logically incorrect.

-------------------------------------------------- --Separation line, above from the Internet----------------------------

I'm talking about a different situation today and a mistake I made. 

A situation where a person has multiple accounts 

public class PersonTest implements Serializable{
    private Long id;
    private String userId;
    private String name;
    private Set<AccountTest> accountTests = new HashSet<AccountTest>() ; // One person corresponds to multiple accounts
…//getter、setter
} 

Account class: 

public class AccountTest implements Serializable {
    private long id; //id
   private String userAccount;// 用户账户
    private PersonTest personTest;
    …//getter、setter
} 

configuration file 

PersonTest class file 

<class name="PersonTest" table="t_persontest">
    <id name="id" type="long">
        <generator class="increment"/>
    </id>
    <property name="name">
        <column name="name" length="64" not-null="true"/>
    </property>
    <property name="userId">
      <column name="userId"length="64" not-null="true"  />
    </property>
     <set name="accountTests"  cascade="all" inverse="true">
      <key column="personTest"  ></key>
        <one-to-many class="AccountTest"/>
    </set>
</class>

 AccountTest configuration file 

<class name="AccountTest" table="t_accountTest">
    <id name="id" type="long" unsaved-value="null">
        <generator class="increment"/></id>
<property name="userAccount">
<column name="userAccount" length="64" not-null="true"/>
</property>
<many-to-one name="personTest" class="PersonTest" column="personTest">
</many-to-one>
                              
</class>

 测试程序 

@Test
public void testMany2oneDoubleAdd2() {
    session.beginTransaction();
    //初始化用户
    PersonTest pt = new PersonTest();
    pt.setName("test1");
    pt.setUserId("ttt");
    AccountTest at1 = new AccountTest();
    at1.setUserAccount("account1");
    at1.setPersonTest(pt);
    pt.getAccountTests().add(at1);
    AccountTest at2 = new AccountTest();
    at2.setUserAccount("account2");
    at2.setPersonTest(pt);
    pt.getAccountTests().add(at2);
    session.save(pt);
    session.getTransaction().commit();
} 

执行到save方法时报的错误如下: 

A different object with the same identifier value was already associated with the session : [com.data.hibernate.prptyref.AccountTest#0]

 

其实也就是在save pt的时候,发现at1at2中的id都已经被赋值了,且都是为0,因此出现了上述报错。

解决的方法也很简单,就是AccountTestidlong变为Long

  具体描述:A different object with the same identifier value was already associated...问题的处理  网上的解释:  hibernate的session缓存之前处理过的数据,比如查询某些信息如User对象,当第二次查询时,从缓存中取出来就可以了。也正是因为session中缓存的存在,导致处理不当时,会出现问题。比如 如下场景: 
  1. 查出来来一个User对象,id1,此时用户再new一个id1的用户(id是用户的主键),执行save操作就会导致NonUniqueObjectException的异常,因为主键值相同,但是引用的对象不同。

  2. 执行更新的过程中也可能存在这样的问题,如下面的程序中(来自于互联网,未验证):

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326518506&siteId=291194637