`

Hibernate 保存对象出现 org.hibernate.NonUniqueObjectException 及解决

阅读更多

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); 
ewDetail.setSubjectId(1000L); 
// 持久化一个临时对象,试图放在session的缓存中,因OID冲突出现异常  
session.save(newDetail); 
// 执行saveOrUpdate同样会出现以上的异常 
// session.saveOrUpdate(newDetail); 
   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".

 

分享到:
评论

相关推荐

    weblogic12 下 org.hibernate.hql.ast.HqlToken

    weblogic12 下最新 org.hibernate.hql.ast.HqlToken解决办法

    hibernate-release-5.2.16.Final.zip

    2. **配置文件**:Hibernate的配置文件(hibernate.cfg.xml)用于定义数据源、实体类、JDBC连接参数等,是启动Hibernate的第一步。 3. **实体类(Entity)**:实体类代表数据库表,通过注解或XML映射文件定义其属性...

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

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

    hibernate-release-5.2.10.Final

    Hibernate,作为Java领域中广泛使用的对象关系映射(ORM)框架,一直以来都是开发人员的重要工具。5.2.10.Final是Hibernate的一个稳定版本,它在前一版本的基础上进行了诸多改进和优化,为开发者提供了更高效、更...

    hibernate源码release-4.1.4.Final版

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

    hibernate-release-5.0.7.Final的源码

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

    hibernate-release-5.3.2.Final

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

    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稳定版(hibernate-release-5.3.23.Final.zip)

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

    hibernate-release-4.3.1.Final.zip

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

    weblogic10.3 org.hibernate.hql.ast.HqlToken报错问题

    总之,解决“weblogic10.3 org.hibernate.hql.ast.HqlToken报错”问题需要对Hibernate和WebLogic有深入的理解,以及对HQL语法的熟练掌握。通过逐步排查和测试,通常能找到问题的根源并成功解决。同时,保持软件更新...

    hibernate-distribution-3.6.7.Final-dist.zip

    2. Configuration:配置对象,负责读取Hibernate的配置文件(hibernate.cfg.xml),并创建SessionFactory。 3. SessionFactory:工厂类,用于创建Session实例,它是线程安全的,通常在应用程序启动时创建一次。 4....

    maven+hibernate

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

    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-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-...

    hibernate-common-annotations.jar

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

    hibernate-release-5.0.7.Final.zip

    Hibernate,作为Java领域中的一个强大的对象关系映射(ORM)框架,极大地简化了数据库操作,使得开发者可以使用面向对象的方式处理数据库事务。在2016年,传智播客黑马程序员发布的Hibernate教程中,特别选用了...

    hibernate.5.1.0.jar全部

    包含hibernate所有所需jar包还有一些其他包日志包、jpa支持包等: 列如:hibernate-core-5.1.0.Final.jar hibernate-ehcache-5.1.0.Final.jar hibernate-entitymanager-5.1.0.Final.jar hibernate-envers-5.1.0....

    hibernate-distribution-3.3.2.GA-dist

    3. **查询语言HQL**:Hibernate Query Language(HQL)是一种面向对象的查询语言,类似于SQL,但更接近Java的语法,可以更方便地进行对象查询。 4. **Criteria查询**:提供了一种基于对象的查询方式,允许开发者...

    hibernate-mapping-3.0.dtd

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

Global site tag (gtag.js) - Google Analytics