org.hibernate.NonUniqueObjectException学习

转载 2011年01月20日 18:33:00

本文源自:http://wdmcln.javaeye.com/blog/154066

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

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

Java代码 复制代码
  1. 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]   
  2.     at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:167)   
  3.     at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:121)   
  4.     at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:186)   
  5.     at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:33)   
  6.     at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:175)   
  7.     at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:27)   
  8.     at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)   
  9.     at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:534)   
  10.     at org.hibernate.impl.SessionImpl.save(SessionImpl.java:522)   
  11.     at org.hibernate.impl.SessionImpl.save(SessionImpl.java:518)   
  12.     at com.legion.km.mapping.kmdb.impl.TargetDBImpl.insertData(TargetDBImpl.java:223)   
  13.     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中定义了一些方法来从缓存中清除一个实例、整个类、集合实例或者整个集合。

相关文章推荐

关于org.hibernate.NonUniqueObjectException出现的一种情况,以及解决方法。

先放一下问题: org.hibernate.NonUniqueObjectException: a different object with the same identifier value...

org.hibernate.NonUniqueObjectException

org.springframework.dao.DuplicateKeyException: A different object with the same identifier value was...

org.hibernate.NonUniqueObjectException报错后,从配置文件中的hibernate-inverse与cascade 得到解决问题

今天,在写代码的时候多复制了行代码,即重复对SET对象添加了两次相同的对象,由于调用保存的方法不是自己写的,其中代码只用了一句session.save(object),就保存了关联的SET对象,但Hi...

Hibernate Session篇--org.hibernate.NonUniqueObjectException分析及解决

1 问题描述: 用hibernate做修改和删除的时候,有时候会遇到 org.hibernate.NonUniqueObjectException 异常, a different object w...

hibernate3.3.2学习笔记---Annotation版本的HelloWorld及org.hibernate.HibernateException错误改正

Teacher.java package com.wanhao; import javax.persistence.Entity; import javax.persistence.Id; @En...

org.hibernate.PropertyNotFoundException

在利用hibernate做ORM时,如果对于hbm文件的属性,在java的pojo类中没有对应的get和set方法,则会产生如下异常: Caused by: org.hibernate.Proper...

org.hibernate.ObjectDeletedException: deleted instance passed to merge: [xxx#<null>]

我们在使用hibernate或JPA的一对多、多对一进行删除操作的时候常会出现org.hibernate.ObjectDeletedException: deleted entity passed t...

关于 java.lang.ClassNotFoundException: org.hibernate.engine.FilterDefinition的问题

java.lang.NoClassDefFoundError: [Lorg/hibernate/engine/FilterDefinition; at java.lang.Class.getDecl...

org.hibernate.HibernateException: Wrong column type

这个问题一般出现在我们使用定长的字符串作为主键(其它字段也可能)的时候,如数据库中的ID为char(16)。虽然很多资料上都说不推荐这样做,但实际上我们在做很多小case的时候自己为了方便也顾不得那么...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)