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.