`

org.hibernate.NonUniqueObjectException学习

阅读更多

Exception:a different object with the same identifier value was already associated with the session
在session中具有相同标识符的不同对象已经关联

1、手动控制事务时,每次持久化操作后将session清除或关闭(衡量性能);
2、覆写对象的hashCode、equals方法,增加部分字段,避免只比较主键来区分不同的对象(Eclipse插件);
3、手动确保需要持久化的对象主键不重复;

org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.legion.km.mapping.hibernate.pojo.TRRResrpt#23878]
	at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:167)
	at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:121)
	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:186)
	at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:33)
	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:175)
	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:534)
	at org.hibernate.impl.SessionImpl.save(SessionImpl.java:522)
	at org.hibernate.impl.SessionImpl.save(SessionImpl.java:518)
	at com.legion.km.mapping.kmdb.impl.TargetDBImpl.insertData(TargetDBImpl.java:223)
	at com.legion.km.mapping.kmdb.impl.KMDBMapping.main(KMDBMapping.java:83)


   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.

 

 

解决方法evict()

不管何时你传递一个对象给save(), update()或者 saveOrUpdate() ,或者不管何时你使用load(), find(), iterate()或者filter()取得一个对象的时候,该对象被加入到Session的内部缓存中。当后继的flush()被调用时,对象的状态会和数据库进行同步。如果你在处理大量对象并且需要有效的管理内存的时候,你可能不希望发生这种同步,evict()方法可以从缓存中去掉对象和它的集合。

Iterator cats = sess.iterate("from eg.Cat as cat"); //a huge result set
while ( cats.hasNext() ) {
    Cat cat = (Cat) iter.next();
    doSomethingWithACat(cat);
    sess.evict(cat);
}
Session也提供了一个contains()方法来判断是否一个实例处于这个session的缓存中。

要把所有的对象从session缓存中完全清除,请调用Session.clear()。

For the JVM-level JCS cache, there are methods defined on SessionFactory for evicting the cached state of an instance, entire class, collection instance or entire collection role.

对于第二层缓存来说,在SessionFactory中定义了一些方法来从缓存中清除一个实例、整个类、集合实例或者整个集合。

 

3
1
分享到:
评论
1 楼 seven_cuit 2009-01-01  
谢谢,很有帮助

相关推荐

    hibernate课件

    **Hibernate 框架详解** ...通过本课件的学习,你将能够熟练掌握Hibernate的基本用法,理解其工作原理,并具备解决实际问题的能力。在后续的lesson中,我们将逐一深入探讨这些知识点,让你的Java ORM技能更上一层楼。

    Hibernate基础

    **Hibernate基础** Hibernate是一款强大的Java持久化框架,它简化了数据库与Java...通过学习和实践这些Hibernate基础知识,开发者可以更好地理解和利用Hibernate的强大功能,提高开发效率,降低数据库操作的复杂性。

    精通 Hibernate:Java 对象持久化技术详解(第2版

    8. 异常处理:了解Hibernate抛出的常见异常,如ConstraintViolationException、NonUniqueObjectException等,并学会如何处理。 9. 高级特性:深入研究Hibernate的高级特性,如动态模型、子查询、分页查询、时间戳、...

    Hibernate入门

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

    hibernate中文开发手册详解

    《Hibernate中文开发手册详解》提供了全面的Hibernate学习资源,无论你是初学者还是有经验的开发者,都能从中找到解答疑惑的答案。通过深入理解并熟练运用Hibernate,你将在Java开发中更加游刃有余,实现高效的数据...

    hibernate常见异常针对于jpa

    ### Hibernate常见异常及解决方案 #### 一、保存了一个父对象,但是它的关联对象没有保存到数据库中 ...通过上述知识点的学习和理解,可以有效地解决Hibernate开发中常见的异常问题,提高开发效率和代码质量。

    JPA学习笔记

    【JPA学习笔记】 JPA(Java Persistence API)是Java平台上的一个ORM(Object-Relational Mapping)规范,它提供了一种将Java对象与数据库表进行映射的机制,简化了数据库操作。JPA允许开发者使用面向对象的方式...

Global site tag (gtag.js) - Google Analytics