hibernate错误:org.hibernate.NonUniqueObjectException:具有相同标识符值的不同对象已经与会话关联
我有两个用户对象,而我尝试保存使用的对象
session.save(userObj);
我收到以下错误:
Caused by: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.pojo.rtrequests.User#com.pojo.rtrequests.User@d079b40b]
我正在使用创build会话
BaseHibernateDAO dao = new BaseHibernateDAO(); rtsession = dao.getSession(userData.getRegion(), BaseHibernateDAO.RTREQUESTS_DATABASE_NAME); rttrans = rtsession.beginTransaction(); rttrans.begin(); rtsession.save(userObj1); rtsession.save(userObj2); rtsession.flush(); rttrans.commit(); rtsession.close(); // in finally block
我也试过在保存之前先做session.clear()
,还是没有运气。
这是第一次我得到会话对象时,用户请求来了,所以我得到为什么说对象是在会议中存在。
有什么build议么?
我曾多次遇到这个错误,并且可能很难追查到…
基本上,hibernate说的是你有两个对象具有相同的标识符(相同的主键),但他们不是同一个对象。
我会build议你分解你的代码,即注释掉一些位,直到错误消失,然后把代码放回去,直到它返回,你应该find它的错误。
它通常通过级联保存发生在对象A和B之间存在级联保存的情况下,但是对象B已经与会话关联但不在B的同一实例上。
你使用的是什么主键生成器?
我问的原因是这个错误是关于如何告诉hibernate确定一个对象的持久状态(即一个对象是持久还是不持久)。 这个错误可能会发生,因为hibernate试图持久化和已经持久化的对象。 实际上,如果你使用保存,hibernate会尝试并坚持这个对象,也许已经有一个对象与会话关联了相同的主键。
例
假设您有一个基于主键组合(列1和列2)的具有10行的表的hibernate类对象。 现在,您在某个时间点从表中删除了5行。 现在,如果你试图再次添加相同的10行,而hibernate试图持久化数据库中的对象,那么已经被删除的5行将被添加而没有错误。 现在剩下的5行已经存在,会抛出这个exception。
所以简单的方法是检查你是否更新/删除了某个属性表中的任何值,然后再尝试再次插入相同的对象
这只是一个点,hibernate使得更多的问题比解决。 在我的情况下,有很多对象具有相同的标识符0,因为它们是新的,没有一个。 数据库生成它们。 某处我读了0信号Id没有设置。 直观的方式来坚持他们迭代他们说,hibernate保存的对象。 但是你不能这么做 – “当然,你应该知道hibernate能够这样做,所以你必须…”所以现在我可以试着把Ids改成Long而不是很长,然后看看它是否工作。 最后,用自己的简单的映射器就可以做到这一点,因为hibernate只是一个额外的不透明的负担。 另一个例子:试图从一个数据库中读取参数并将其保存在另一个数据库中,迫使你几乎所有的工作都要手动完成。 但是,如果你必须这样做,使用hibernate只是额外的工作。
使用session.evict(object);
evict()
方法的function用于从会话caching中删除实例。 因此,第一次保存对象时,通过调用session.save(object)
方法保存对象,然后从caching中逐出对象。 在调用evict()之前,通过调用session.saveOrUpdate(object)
或session.update(object)
来更新对象。
正如有人已经指出,我遇到了这个问题,当我有cascade=all
在one-to-many
关系的两端,所以让我们假设A – > B(从A和多对一的一对多从B),并更新A的实例B,然后调用saveOrUpdate(A),它导致了一个循环的保存请求,即保存B的触发器保存触发保存的A …,在第三个实例作为实体(的A)被试图被添加到sessionPersistenceContext的duplicateObjectexception被抛出。
我可以通过从一端删除级联来解决它。
当您使用相同的会话对象进行读取和写入时,可能会发生这种情况。 怎么样? 假设你已经创build了一个会话。 您从员工表中读取主键Emp_id = 101的logging现在您已经使用Java修改logging。 你要将雇员logging保存在数据库中。 我们在这里的任何地方都没有闭幕。 因为读到的对象也持续在会话中。 它与我们希望写的对象相冲突。 因此,这个错误来了。
获取会话内的对象,这里是一个例子:
MyObject ob = null; ob = (MyObject) session.get(MyObject.class, id);
我碰到这个问题:
- 删除一个对象(使用HQL)
- 立即存储一个具有相同ID的新对象
我通过在删除之后刷新结果来解决它,并在保存新对象之前清除caching
String delQuery = "DELETE FROM OasisNode"; session.createQuery( delQuery ).executeUpdate(); session.flush(); session.clear();
我也遇到了这个问题,很难find错误。
我遇到的问题如下:
这个对象已经被一个具有不同hibernate会话的Dao读取了。
为了避免这种exception,只需重新读取将要保存/更新这个对象的dao的对象。
所以:
class A{ readFoo(){ someDaoA.read(myBadAssObject); //Different Session than in class B } } class B{ saveFoo(){ someDaoB.read(myBadAssObjectAgain); //Different Session than in class A [...] myBadAssObjectAgain.fooValue = 'bar'; persist(); } }
希望节省一些人很多时间!
你的Id映射是否正确? 如果数据库负责通过标识符创buildId,则需要将您的userobject映射到..
请检查您是否忘记将@GenerateValuereplace为@Id列。 电影和stream派之间的多对多关系也有同样的问题。 程序抛出了Hibernate Error:org.hibernate.NonUniqueObjectException:具有相同标识符值的不同对象已经与会话错误相关联。 我后来发现,我只是要确保你有@GenerateValue的GenreId get方法。
只要检查id是否为空或0就好
if(offersubformtwo.getId()!=null && offersubformtwo.getId()!=0)
在添加或更新的内容从forms设置为Pojo
我遇到这个删除对象的问题,既没有驱逐也没有明确的帮助。
/** * Deletes the given entity, even if hibernate has an old reference to it. * If the entity has already disappeared due to a db cascade then noop. */ public void delete(final Object entity) { Object merged = null; try { merged = getSession().merge(entity); } catch (ObjectNotFoundException e) { // disappeared already due to cascade return; } getSession().delete(merged); }
试试这下面的工作对我来说!
在hbm.XML文件中1.我们需要设置类标签的dynamic-update属性为“true”,例如: <class dynamic-update="true">
2.设置属于唯一列的generator标签的class属性为“身份”如
:<generator class ="Identity">
注意:将唯一列作为标识进行分配。
谢谢。
我有一个类似的问题。 在我的情况下,我忘记了将数据库中的increment_by
值设置为与cache_size
和allocationSize
所使用的值相同。 (箭头指向提到的属性)
SQL:
CREATED 26.07.16 LAST_DDL_TIME 26.07.16 SEQUENCE_OWNER MY SEQUENCE_NAME MY_ID_SEQ MIN_VALUE 1 MAX_VALUE 9999999999999999999999999999 INCREMENT_BY 20 <- CYCLE_FLAG N ORDER_FLAG N CACHE_SIZE 20 <- LAST_NUMBER 180
Java的:
@SequenceGenerator(name = "mySG", schema = "my", sequenceName = "my_id_seq", allocationSize = 20 <-)
我有同样的错误,我正在取代我的设置与从jackson新的一个。
为了解决这个问题,我保留了现有的设置,我使用retainAll
从旧的设置中删除了未知的元素。 然后我用addAll
添加新的。
this.oldSet.retainAll(newSet); this.oldSet.addAll(newSet);
没有必要有会议和操纵它。
另一件事对我来说是使实例变长,而不是长
我有我的主键variables长ID; 改为长ID; 工作
祝一切顺利
你总是可以做一个会话刷新。 刷新会同步所有对象在会话中的状态(如果我错了,请有人纠正我),也许这会在某些情况下解决您的问题。
实现你自己的equals和hashcode也可以帮助你。
你可以检查你的级联设置。 您的模型上的级联设置可能会导致此问题。 我删除了级联设置(基本上不允许级联插入/更新),这解决了我的问题
我也发现这个错误。 对我而言,确保主键(即自动生成的)不是一个PDT(即long,int等),而是一个对象(即Long,Integer等)
当你创build你的对象来保存它时,确保你传递null而不是0。
我是NHibernate的新手,我的问题是,我用一个不同的会话来查询我的对象比我保存它。 所以保存会议不知道对象。
这似乎很明显,但从阅读以前的答案我到处寻找2个对象,而不是2个会话。
这有帮助吗?
User userObj1 = new User(); User userObj2 = userObj1; . . . rtsession.save(userObj1); rtsession.save(userObj2);
@GeneratedValue(strategy = GenerationType.IDENTITY),将这个注解添加到实体bean中的主键属性应该可以解决这个问题。
我解决了这个问题。
其实这是因为我们忘记了bean类中PK属性的生成器types的实现。 所以使它像任何types
@Id @GeneratedValue(strategy=GenerationType.IDENTITY) private int id;
当我们坚持bean的对象时,每个对象获得了相同的ID,所以第一个对象被保存,当另一个对象被持久化时,通过这种types的Exception: org.hibernate.NonUniqueObjectException:
具有相同标识符值的另一个对象是已经与会议相关联。
我已经解决了类似的问题:
plan = (FcsRequestPlan) session.load(plan.getClass(), plan.getUUID()); while (plan instanceof HibernateProxy) plan = (FcsRequestPlan) ((HibernateProxy) plan).getHibernateLazyInitializer().getImplementation();
在重复对象开始的位置之前,应closures会话,然后开始新的会话
session.close(); session = HibernateUtil.getSessionFactory().openSession();
所以这样在一个会话中不会有多个具有相同标识符的实体。
发生这个问题是因为在同一个hibernate会话中,你试图保存两个具有相同标识符的对象。有两个解决scheme:
-
这是因为你没有正确configuration你的mapping.xml文件的id字段,如下所示:
<id name="id"> <column name="id" sql-type="bigint" not-null="true"/> <generator class="hibernateGeneratorClass"</generator> </id>
-
重载getsession方法来接受像isSessionClear这样的参数,并在返回当前会话之前清除会话,如下所示
public static Session getSession(boolean isSessionClear) { if (session.isOpen() && isSessionClear) { session.clear(); return session; } else if (session.isOpen()) { return session; } else { return sessionFactory.openSession(); } }
这将导致现有会话对象被清除,即使hibernate没有生成唯一的标识符,假设您已经使用类似于Auto_Increment的方式正确地为主键configuration了数据库,它应该为您工作。
解决这个问题的一个解决方法是在你进行任何更新之前尝试从hibernate cache / db中读取对象,然后保存。
例:
OrderHeader oh = orderHeaderDAO.get(orderHeaderId); oh.setShipFrom(facilityForOrder); orderHeaderDAO.persist(oh);
注意:请记住,这不能解决根本原因,但解决了这个问题。
否则,比wbdarby所说的,它甚至可以通过将对象的标识符提供给HQL来获取对象时发生。 在尝试修改对象字段并将其保存回数据库(修改可能是插入,删除或更新) 的情况下 ,会出现此错误。 尝试在保存修改的对象之前清除hibernate会话,或创build一个全新的会话。
希望我帮助;-)
晚会,但可能有助于未来的用户 –
我在使用getsession()
selectlogging时遇到此问题,并使用相同的会话再次更新具有相同标识符的另一条logging导致问题。 在下面添加代码。
Customer existingCustomer=getSession().get(Customer.class,1); Customer customerFromUi;// This customer details comiong from UI with identifer 1 getSession().update(customerFromUi);// Here the issue comes
这绝不应该这样做。 解决scheme是在更新之前退出会话或更改业务逻辑。
这是因为你打开一个会话可能是为了获取数据,然后忘记closures它。 当你删除你再次打开会话,然后它成为错误。
解决scheme:每个function都应该打开和closures会话
session.getTransaction.begin(); /* your operation */ session.close()
- JPAhibernate多对多级联
- org.hibernate.MappingException:无法确定types:java.util.Set
- 如何将inheritance策略与JPA注释和Hibernate混合?
- 在Hibernate Validator 4.1+中,@NotNull,@NotEmpty和@NotBlank有什么区别?
- hibernate与JPA与JDO – 每个的利弊?
- 存储库模式 – 如何理解它,以及它如何与“复杂”实体协同工作?
- Hibernate和Spring Data JPA有什么区别?
- 何时以及如何使用hibernate二级caching?
- 如何使用JPA和Hibernate在UTC时区存储date/时间和时间戳