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

Hibernate throws "deleted object would be re-saved by cascade (remove deleted object from associations)"

我有父对象 (DDetails),它包含 7 个子对象(DPricingElements、DCoverages、DElectricalLimit、DVehicleDetails、DAAttributes、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.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();

那肯定会删的