已删除的对象将通过级联重新保存(从关联中删除已删除的对象)

Mah*_*leh 46 hibernate jpa one-to-many java-ee

我有以下两个实体:

1-播放列表:

@OneToMany(fetch = FetchType.EAGER, mappedBy = "playlist", orphanRemoval = true, cascade =   CascadeType.ALL)
@OrderBy("adOrder")
private Set<PlaylistadMap> PlaylistadMaps = new HashSet<PlaylistadMap>(0);
Run Code Online (Sandbox Code Playgroud)
  • CascadeType.ALL:在保存或更新播放列表实体时,需要在PlaylistadMap集合上进行保存和更新.
  • 删除播放列表实体时需要使用orphanRemoval = true:还应删除PlaylistadMap引用.

2- PlaylistadMap:

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "fk_playlist", referencedColumnName = "pkid", nullable = false)
private Playlist playlist;
Run Code Online (Sandbox Code Playgroud)

使用getCurrentSession().delete();我删除播放列表时,我收到以下异常:

org.springframework.dao.InvalidDataAccessApiUsageException: deleted object would be re-saved by cascade (remove deleted object from associations): [com.xeno.advertisingsuite.web.domain.PlaylistadMap#6]; nested exception is org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): [com.xeno.advertisingsuite.web.domain.PlaylistadMap#6]
    at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:657)
    at org.springframework.orm.hibernate3.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:793)
    at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:664)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    at $Proxy54.deletePlayList(Unknown Source)
    at com.xeno.advertisingsuite.web.beans.PlayListBean.deletePlaylist(PlayListBean.java:282)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.el.parser.AstValue.invoke(AstValue.java:262)
    at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278)
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
    ... 103 more
Caused by: org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): [com.xeno.advertisingsuite.web.domain.PlaylistadMap#6]
    at org.hibernate.impl.SessionImpl.forceFlush(SessionImpl.java:1220)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:188)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:117)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
    at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:677)
    at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:669)
    at org.hibernate.engine.CascadingAction$5.cascade(CascadingAction.java:252)
    at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:392)
    at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:335)
    at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:204)
    at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:425)
    at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:362)
    at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:338)
    at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:204)
    at org.hibernate.engine.Cascade.cascade(Cascade.java:161)
    at org.hibernate.event.def.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:154)
    at org.hibernate.event.def.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:145)
    at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:88)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1206)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:375)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:137)
    at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:656)
Run Code Online (Sandbox Code Playgroud)

请告知如何解决此异常.

Tom*_*son 43

解决方案是完成异常消息告诉您的操作:

引起:org.hibernate.ObjectDeletedException:已删除的对象将通过级联重新保存(从关联中删除已删除的对象)

从它所在的关联(集合,列表或映射)中删除已删除的对象.特别是,我怀疑,来自PlayList.PlaylistadMaps.仅删除对象是不够的,您必须将其从引用它的任何级联集合中删除.

实际上,由于您的集合已经存在orphanRemoval = true,因此您无需明确删除它.你只需要从集合中删除它.

  • Intellij有一个名为"显示引用对象"的新功能,并且完全按照它的建议完成,我可以通过将对象引用设置为null来解决此问题. (5认同)

Mah*_*leh 22

FetchType更改为Lazy后问题解决了

  • Hibernate有时很奇怪. (18认同)
  • 有没有其他解决方案,使FetchType Lazy真的不是一个选项. (8认同)
  • @Sikorski - 我遇到了同样的问题,但遵循了 [here](http://gullele.wordpress.com/2010/08/04/deleted-object-would-be-re-saved-by-cascade- remove-deleted-object-from-associations/) 对我来说效果很好。 (2认同)

Dmi*_*urg 6

如果您不知道,哪个集合包含您的对象

在我的情况下,很难应用TomAnderson的解决方案,因为我不知道什么是集合,它保存了一个对象的链接,所以这里是知道的方式,哪些对象保存到已删除的链接的链接:在调试器你应该在抛出异常之前进入最低执行堆栈级别,应该有一个名为的变量entityEntry,所以你PersistenceContext从这个变量得到一个对象:entityEntry.persistenceContext.

对我来说persistenceContext是一个实例,StatefulPersistenceContext并且这个实现有一个private字段parentsByChild,您可以从中检索有关包含该元素的集合的信息.

我正在使用Eclipse调试器,所以很难直接检索这个私有字段,所以我使用Detail Formatter(在调试时如何直接在IDE中查看其他对象的私有字段?)

获得此信息后,可以应用TomAnderson的解决方案.