`
jackytang520
  • 浏览: 138527 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Hibernate 保存对象出现 org.hibernate.NonUniqueObjectExce

    博客分类:
  • Java
阅读更多
Hibernate save 在 session 中已存在相同 OID(主键) 的对象,会出现异常,详细内容如下:
Exception in thread "main" org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.unmi.LoanDetail#1]
 at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:168)
 at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:121)
 at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:187)
 at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:33)
 at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:172)
 at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:27)
 at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
 at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:535)
 at org.hibernate.impl.SessionImpl.save(SessionImpl.java:523)
 at org.hibernate.impl.SessionImpl.save(SessionImpl.java:519)
 at com.unmi.Test.main(Test.java:44) 

重现以上错误的代码如下(去除了事物控制的代码行):
Session session  =  HibernateSessionFactory.getSession();
      
     // 加载OID为1L的对象,会被放在session缓存中   
     LoanDetail detail  =  (LoanDetail)session.get(LoanDetail. class ,  1L );
     
     // new 一个OID也为1L的临时对象  
     LoanDetail newDetail  =   new  LoanDetail( 1L );
    newDetail.setSubjectId( 1000L );
    
     // 持久化一个临时对象,试图放在session的缓存中,因OID冲突出现异常 
     session.save(newDetail);

     // 执行saveOrUpdate同样会出现以上的异常
     // session.saveOrUpdate(newDetail); 


解决方法:
   1) 如果用的 hibernate 2, 需要在get/load/query到持久化对象,赋上新的属性值,再 save/update/saveOrupdate.
      对以上代码就是:不能 new 一个session中已存在OID的对象,直接
      detail.setSubjectId(1000L);
      session.save(detail);
      session.save()一个持久化对象时,会转化成update调用。

   2) 使用 hibernate 3 的 merge 方法. session.merge(newDetail)即可,它会在 session 缓存中找到持久化对象,把新对象的属性赋过去,再保存原session中的持久化对象。
      如果在session或数据库中没有的对象,用merge方法的话,它也能够帮你把记录 insert 到表中,相当于 save 方法。

上面是一个简单的例子,实际业务中可能是经过一番复杂的操作后自己也很难搞清楚 new 的一个新对象在 session/数据库中是否已存在。所以第一种方法你需要清楚你的每一个对象状态,第二种方法在 hibernate 3 中就比较通用一些。

附 hibernate javadoc 对 session.merge() 方法的注释:
Copy the state of the given object onto the persistent object with the same identifier. If there is no persistent instance currently associated with the session, it will be loaded. Return the persistent instance. If the given instance is unsaved, save a copy of and return it as a newly persistent instance. The given instance does not become associated with the session. This operation cascades to associated instances if the association is mapped with cascade="merge".

The semantics of this method are defined by JSR-220.

分享到:
评论

相关推荐

    hibernate-configuration-3.0.dtd、hibernate-mapping-3.0.dtd

    例如,`hibernate.connection.driver_class`对应数据库驱动,`hibernate.dialect`指定了使用的数据库方言,`hibernate.show_sql`可以控制是否打印执行的SQL语句。 总的来说,理解和熟练运用`hibernate-...

    HIbernate4.3.6整合c3p0所需jar

    org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.connections.spi.ConnectionProvider] at org.hibernate.service.internal....

    hibernate jar包:hibernate-commons-annotations-4.0.1.Final.jar等

    Hibernate.jar包,Hibernate可以应用在任何使用JDBC的场合,包含 hibernate-commons-annotations-4.0.1.Final.jar hibernate-core-4.1.12.Final.jar hibernate-ehcache-4.1.12.Final.jar hibernate-entitymanager-...

    hibernate-core-5.4.24.Final.jar

    hibernate-core-5.4.24.Final.jar

    Hibernate稳定版(hibernate-release-5.3.23.Final.zip)

    Hibernate稳定版(hibernate-release-5.3.23.Final.zip),Hibernate ORM 是一个为应用程序、库和框架提供对象/关系映射 (ORM) 支持的库。它还提供了 JPA 规范的实现,这是 ORM 的标准 Java 规范。

    hibernate-release-5.0.7.Final的源码

    hibernate-release-5.0.7.Final的源码,有需要的人可以下载

    Hibernate稳定版(hibernate-release-5.4.32.Final.zip)

    Hibernate稳定版(hibernate-release-5.4.32.Final.zip),Hibernate ORM 是一个为应用程序、库和框架提供对象/关系映射 (ORM) 支持的库。它还提供了 JPA 规范的实现,这是 ORM 的标准 Java 规范。

    org.springframework.orm.hibernate3.LocalSessionFactoryBean

    ### 关于 "org.springframework.orm.hibernate3.LocalSessionFactoryBean" 未找到问题的知识点解析 #### 一、问题背景 在开发基于Spring与Hibernate整合的应用时,可能会遇到“`org.springframework.orm.hibernate...

    hibernate-validator-6.0.2.Final-dist

    hibernate-validator-6.0.2.Final-dist hibernate-validator-6.0.2.Final-dist hibernate-validator-6.0.2.Final-dist

    hibernate源码release-4.1.4.Final版

    2. Session:是与数据库交互的接口,提供持久化对象的保存、删除、更新和检索功能。它还支持事务管理和缓存机制。 3. Query与Criteria:提供了两种查询方式,HQL(Hibernate Query Language)是一种面向对象的查询...

    hibernate-mapping-3.0.dtd

    hibernate-mapping-3.0.dtd 配置后,就会在xml中进行提示

    hibernate-release-5.3.2.Final

    使用Hibernate ORM通常需要配置Hibernate配置文件(hibernate.cfg.xml),定义数据库连接参数、缓存策略等。实体类需使用注解标注属性与数据库字段的对应关系,然后通过SessionFactory创建Session,进而进行数据操作...

    hibernate-release-4.3.1.Final.zip

    例如,通过配置`hibernate.cfg.xml`文件设置数据库连接,编写实体类并使用注解进行ORM映射,然后使用SessionFactory创建Session对象来执行CRUD操作。同时,Hibernate提供了HQL(Hibernate Query Language)和...

    Hibernate5x安装包 hibernate-release-5.0.7.Final

    javaEE框架Hibernate安装包 hibernate-release-5.0.7.Final

    Hibernate 离线的配置方法(hibernate-mapping-3.0.dtd)

    因为Hibernate在读出hbm.xml文件时需要通过网络读取到hibernate-mapping-3.0.dtd 文件。 如果没有网络不能正常工作。 所以提供上述文件。 以及hibernate-mapping-3.0.dtd,hibernate-configuration-3.0.dtd提供下载...

    hibernate-validator-6.0.18.Final-sources.jar

    java运行依赖jar包

    hibernate-entitymanager-3.4.0.GA.rar

    hibernate-entitymanager-3.4.0.GA.rar hibernate-entitymanager-3.4.0.GA.rar hibernate-entitymanager-3.4.0.GA.rar hibernate-entitymanager-3.4.0.GA.rar hibernate-entitymanager-3.4.0.GA.rar hibernate-...

    maven+hibernate

    标题 "maven+hibernate" 暗示我们讨论的是使用 Maven 作为构建工具,与 Hibernate 这一流行的对象关系映射(ORM)框架整合的项目。在Java开发中,Maven 和 Hibernate 是两个非常重要的组件。Maven 用于自动化项目的...

    hibernate-validator-5.2.4.Final.jar

    Hibernate Validator 是一个基于 Bean Validation 规范的实现,是 Hibernate 项目的一部分,主要用于进行 Java 对象的验证。它提供了丰富的约束注解和自定义验证逻辑,使得开发者能够在 Java 应用程序中轻松地进行...

    hibernate-common-annotations.jar

    "hibernate-commons-annotations.jar"包含了所有上述的JPA注解以及Hibernate特定的扩展注解,如@org.hibernate.annotations.Entity、@org.hibernate.annotations.Table等。这些注解使得开发者无需编写XML配置文件,...

Global site tag (gtag.js) - Google Analytics