`
gjs_ht
  • 浏览: 8945 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

hibernate的NonUniqueObjectException错误处理

阅读更多

 

具体描述:A different object with the same identifier value was already associated...问题的处理 

网上的解释: 

hibernate的session缓存之前处理过的数据,比如查询某些信息如User对象,当第二次查询时,从缓存中取出来就可以了。也正是因为session中缓存的存在,导致处理不当时,会出现问题。比如如下场景: 

  1. 查出来来一个User对象,id1,此时用户再new一个id1的用户(id是用户的主键),执行save操作就会导致NonUniqueObjectException的异常,因为主键值相同,但是引用的对象不同。

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

      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);  

 

错误原因:传进来的A是一个独立实体,加载B后,b对象会加载一个a在这个session中,如此在update(a)时,session重新加载并update,如此重复了。 

解决办法:  

public void update_A_B(A a) {  

    B b=findByA(a);  

    update(b);  

    a=b.getMany_to_one_A();  

    update(a);  

  

除此之外,网上还给出了解决办法:

  1. session.evict(objPO);或者在update之前session.clear();,清除缓存,或者调用evict方法,将当前对象设置为detached的状态

  2. sessionmerge方法,但是这个方法可能逻辑不对。

----------------------------------------------------分割线,上面来自互联网----------------------------

我今天说的是另一种情形,也是我犯的一个错误。 

一个人拥有多个账户的情形 

public class PersonTest implements Serializable{
    private Long id;
    private String userId;
    private String name;
    private Set<AccountTest> accountTests = new HashSet<AccountTest>(); //一个人对应多个账户
…//getter、setter
} 

账户类: 

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

配置文件 

PersonTest类的文件 

<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的配置文件 

<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

分享到:
评论

相关推荐

    Hibernate入门

    了解Hibernate常见的异常,如`HibernateException`、`NonUniqueObjectException`、`ObjectNotFoundException`等,以便在编程时进行正确的错误处理。 ### 9. 事务管理 使用Transaction接口进行事务操作,如begin(),...

    hibernate 事务管理注意事项

    然而,在这种情况下,需要注意`org.hibernate.NonUniqueObjectException`异常的处理,该异常通常发生在同一个会话中试图保存具有相同标识符但不同对象的情况。例如: ```java public class ExampleServiceImpl { ...

    hibernate基础等

    Hibernate 是一款开源的Java语言下的对象关系映射(ORM)框架,它极大地简化了数据库操作,使得开发者可以使用面向对象的方式来处理数据库事务,而无需过多关注底层SQL语句的编写。在Java开发中,Hibernate扮演着...

    数据库相关知识

    - 错误处理:当对象状态不匹配或ID设置不正确时,Hibernate会抛出特定异常,如`PersistentObjectException`, `IdentifierGenerationException`, `TransientObjectException`, `NonUniqueObjectException`等。...

    JPA学习笔记

    如`PersistenceException`, `EntityExistsException`, `NonUniqueObjectException`, `TransactionRequiredException`等,这些异常通常反映了JPA操作中的错误情况,需要根据异常信息进行排查和处理。 总之,JPA作为...

Global site tag (gtag.js) - Google Analytics