java - hibernate 抛出 "deleted object would be re-saved by cascade (remove deleted object from associations)"

标签 java hibernate orm hibernate-mapping cascade

我有父对象(DDetails),其中包含7个子对象(DPricingElements、DCoverages、DElectricalLimit、DVehicleDetails、DAttributes、DNonElecLimit、DPartyDetails),我正在删除父对象,这也会删除子对象。使用下面的代码,

Query query = session.createQuery("FROM DDetails where DQuote.Id =:Id").setParameter("Id", Id);
List<DDetails> quertList = query.list();
session.delete(dDetails);

它也删除了子级和父级,在一些罕见的情况下,我遇到了异常org.hibernate.ObjectDeletedException:已删除的对象将通过级联重新保存(从关联中删除已删除的对象):[com.model.DDetails#257309]

我想知道级联关联,但上面的代码在生产环境中运行了 2 年多。无法产生相同的异常,并且异常得到了测试、UAT 环境。

请查找日志跟踪;

Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: deleted object would be re-saved by cascade (remove deleted object from associations): [com.model.DDetails#257309]; nested exception is org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): [com.model.DDetails#257309]
    at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:674)
    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 com.sun.proxy.$Proxy70.updateVehicleDetails(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:180)
    at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96)
    ... 38 more
Caused by: org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): [com.model.DDetails#257309]
    at org.hibernate.impl.SessionImpl.forceFlush(SessionImpl.java:1230)
    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:685)
    at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:677)
    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:1216)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:383)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:133)
    at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:656)
    ... 51 more

请找到DDetails.hbm.xml

<set name="DPricingElementses" table="D_PRICING_ELEMENTS"
            inverse="true" lazy="false" fetch="select" cascade="all-delete-orphan">
            <key>
                <column name="_ID" precision="10" scale="0" />
            </key>
            <one-to-many class="com.model.DPricingElements" />
        </set>

        <set name="DCoverageses" table="D_COVERAGES" inverse="true"
            lazy="false" fetch="select" cascade="all-delete-orphan">
            <key>
                <column name="_ID" precision="15" scale="0" />
            </key>
            <one-to-many class="com.model.DCoverages" />
        </set>
        <set name="DElectricalLimits" table="D_ELECTRICAL_LIMIT"
            inverse="true" lazy="false" fetch="select" cascade="all-delete-orphan">
            <key>
                <column name="_ID" precision="10" scale="0" />
            </key>
            <one-to-many class="com.model.DElectricalLimit" />
        </set>
        <set name="DVehicleDetailses" table="D_VEHICLE_DETAILS"
            inverse="true" lazy="false" fetch="select" cascade="all-delete-orphan">
            <key>
                <column name="_ID" precision="10" scale="0" />
            </key>
            <one-to-many class="com.model.DVehicleDetails" />
        </set>
        <set name="DAttributeses" table="D_ATTRIBUTES"
            inverse="true" lazy="false" fetch="select" cascade="all-delete-orphan">
            <key>
                <column name="_ID" precision="10" scale="0" />
            </key>
            <one-to-many class="com.model.DAttributes" />
        </set>
        <set name="DNonElecLimits" table="D_NON_ELEC_LIMIT"
            inverse="true" lazy="false" fetch="select" cascade="all-delete-orphan">
            <key>
                <column name="_ID" precision="10" scale="0" />
            </key>
            <one-to-many class="com.model.DNonElecLimit" />
        </set>
        <set name="DPartyDetailses" table="D_PARTY_DETAILS"
            inverse="true" lazy="false" fetch="select" cascade="all-delete-orphan">
            <key>
                <column name="_ID" precision="22" scale="0" not-null="true" />
            </key>
            <one-to-many class="com.model.DPartyDetails" />
        </set>

org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations):的帮助下我也更改了代码,但仍然出现相同的异常。

for (DDetails dDetails: quertList) {
 if (dDetails.getDNonElecLimits() != null && !dDetails.getDNonElecLimits().isEmpty()) {
  for (DNonElecLimit a: new ArrayList < DNonElecLimit > (dDetails.getDNonElecLimits())) {
   dDetails.getDNonElecLimits().remove(a);
   //session.delete(a); 
  }
 }

 if (dDetails.getDElectricalLimits() != null && !dDetails.getDElectricalLimits().isEmpty()) {
  for (DElectricalLimit b: new ArrayList < DElectricalLimit > (dDetails.getDElectricalLimits())) {
   dDetails.getDElectricalLimits().remove(b);
   //session.delete(b); 
  }
 }

 if (dDetails.getDAttributeses() != null && !dDetails.getDAttributeses().isEmpty()) {
  for (DAttributes c: new ArrayList < DAttributes > (dDetails.getDAttributeses())) {
   dDetails.getDAttributeses().remove(c);
  }
 }

 if (dDetails.getDCoverageses() != null && !dDetails.getDCoverageses().isEmpty()) {
  for (DCoverages d: new ArrayList < DCoverages > (dDetails.getDCoverageses())) {
   dDetails.getDCoverageses().remove(d);
  }
 }

 if (dDetails.getDPricingElementses() != null && !dDetails.getDPricingElementses().isEmpty()) {
  for (DPricingElements e: new ArrayList < DPricingElements > (dDetails.getDPricingElementses())) {
   dDetails.getDPricingElementses().remove(e);
  }

 }

 if (dDetails.getDVehicleDetailses() != null && !dDetails.getDVehicleDetailses().isEmpty()) {
  for (DVehicleDetails f: new ArrayList < DVehicleDetails > (dDetails.getDVehicleDetailses())) {
   dDetails.getDVehicleDetailses().remove(f);
  }

 }

 if (dDetails.getDThirdPartyDetailses() != null && !dDetails.getDThirdPartyDetailses().isEmpty()) {
  for (DThirdPartyDetails g: new ArrayList < DThirdPartyDetails > (dDetails.getDThirdPartyDetailses())) {
   dDetails.getDThirdPartyDetailses().remove(g);
  }
 }

 session.delete(dDetails);
 session.flush();
}

最佳答案

Its deleting child and parent too, some rare scenario i got an exception org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): [com.model.DDetails#257309]

这是因为,有时,您有一个父实体通过级联保留对 DDetails 的引用,并且您没有清除该引用。

同时,一个简单的解决方法是执行以下操作:

session.clear();

session.createQuery("delete from DDetails where DQuote.Id =:Id")
.setParameter("Id", Id)
.executeUpdate();

这肯定会删除它。

关于java - hibernate 抛出 "deleted object would be re-saved by cascade (remove deleted object from associations)",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47196058/

相关文章:

java - JDBC 内置函数和准备好的语句

java - 我的插入排序的实现

hibernate :@UniqueConstraint与@ManyToOne字段?

c# - 级联还是不级联? ("object references an unsaved transient instance"错误)

java - openjpa2.0如何在运行时增强实体?

java - 如何在 Hibernate 中使用第三张表映射两个实体之间的一对多连接?

java - 添加实体列表时的Spring Data jpa( hibernate )空指针异常

java - 强制停止线程

hibernate - 使用 JPA 和 Hibernate 生成 SQLite 动态数据库和数据填充

Java Hibernate MariaDB DDL 执行