Java >> Java Tutorial >  >> Java

Eine Sammlung mit cascade="all-delete-orphan" wurde nicht mehr von der besitzenden Entitätsinstanz referenziert

Vor kurzem bin ich auf ein interessantes Problem gestoßen, als ich an der Persistenz des Ruhezustands gearbeitet habe. Ich hatte ein Objekt certificate die ein untergeordnetes Sammlungsobjekt certificateProperties hatte . Beim Aktualisieren eines Objekts, das auf certificate verweist , es wird weiterhin ein Fehler wie folgt ausgegeben:

A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance: com.betterjavacode.model.Certificate.certificateProperties; nested exception is org.hibernate.HibernateException: A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance: com.infor.security.sts.config.model.Certificate.certificateProperties
 at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:333)
 at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:244)
 at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:521)
 at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:765)
 at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:734)
 at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:518)
 at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:292)
 at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
 at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
 at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:133)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
 at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
 at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:57)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
 at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
 at com.sun.proxy.$Proxy213.save(Unknown Source)

Es war überraschend, dass dieser Fehler zufällig auftauchte. Ich habe mich gefragt, ob ich orphanRemoval verpasst habe Tag auf meinem Objekt certificate für certificateProperties , aber es war da. Es war also definitiv nicht das Problem. Denken Sie auch daran, dass ich cascade = CascadeType.ALL verwendet habe für kaskadierende Persistenz von certificate .

Lösung

Nun, wenn Sie es bemerken, liefert Hibernate genügend Informationen über den Fehler, um zu bemerken, was passiert. Hibernate beschwert sich, dass es nicht in der Lage ist, die Änderung für das untergeordnete Sammlungsobjekt certificateProperties zu verfolgen während es im übergeordneten Objekt certificate gesetzt wird . Hibernate erfordert, dass ein übergeordnetes Objekt ein untergeordnetes Sammlungsobjekt vollständig besitzt.

Um dieses Problem zu beheben, war die Lösung einfach

Old Code

    public void setCertificateProperties(Set<CertificateProperty> certificateProperties)
    {
        this.certificateProperties = certificateProperties; 
    }

Solution Code
    private Set<CertificateProperty> certificateProperties = new HashSet<>();

    public void setCertificateProperties(Set<CertificateProperty> certificateProperties)
    {
        this.certificateProperties.addAll(certificateProperties);
    }

Schlussfolgerung

Wir haben gezeigt, wie Hibernate mit Persistenz im Kaskadenbetrieb umgehen kann. Wenn Ihnen dieser Beitrag gefallen hat, abonnieren Sie bitte meinen Blog hier.


Java-Tag