Hi all,
I got an issue about a cascading deletion :
I got a "Parent" table in which a column is a foreign key of a "child" table. There is a constraint on this foreign key : a value in the "child" table must match a value in the "parent" table.
My goal is to delete rows from the "child" table when a row from the "parent" table is deleted (rows linked by the foreign key from the "child" table).
I searched the web, and I noticed it's a common problematic and apparently easy to resolve, but each times I delete the "Parent" object, i got the following exception :
Code:
3187 [main] WARN org.hibernate.util.JDBCExceptionReporter - SQL Error: 2292, SQLState: 23000
3187 [main] ERROR org.hibernate.util.JDBCExceptionReporter - ORA-02292: violation de contrainte (TOM2_TEST1.FK_DELEGATION_DEMANDE) d'intégrité - enregistrement fils existant
3203 [main] ERROR org.hibernate.event.def.AbstractFlushingEventListener - Could not synchronize database state with session
org.hibernate.exception.ConstraintViolationException: could not delete: [fr.gipcps.smtom.data.model.DemandeModifTitulaireVO#123]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:94)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2569)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2725)
at org.hibernate.action.EntityDeleteAction.execute(EntityDeleteAction.java:97)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:172)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:365)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:137)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:655)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:732)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:701)
at org.springframework.test.AbstractTransactionalSpringContextTests.endTransaction(AbstractTransactionalSpringContextTests.java:355)
at fr.gipcps.smtom.data.dao.impl.TraiterSuppressionDemandeModifTitulaireTest.testSupprimerDemandeModifTitulaire(TraiterSuppressionDemandeModifTitulaireTest.java:80)
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 junit.framework.TestCase.runTest(TestCase.java:168)
at junit.framework.TestCase.runBare(TestCase.java:134)
at org.springframework.test.ConditionalTestCase.runBare(ConditionalTestCase.java:76)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:124)
at junit.framework.TestSuite.runTest(TestSuite.java:232)
at junit.framework.TestSuite.run(TestSuite.java:227)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: java.sql.SQLIntegrityConstraintViolationException: ORA-02292: violation de contrainte (TOM2_TEST1.FK_DELEGATION_DEMANDE) d'intégrité - enregistrement fils existant
at oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:85)
at oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:133)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:206)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:455)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:413)
at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:1034)
at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:194)
at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:953)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1222)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3387)
at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:3468)
at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeUpdate(OraclePreparedStatementWrapper.java:1350)
at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:46)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2548)
... 35 more
the message is "Integrity constraint violation(TOM2_TEST1.FK_DELEGATION_DEMANDE) - existing son row"
Here is my Hibernate mapping :
Parent Table :
Code:
[...]
<set name="listeModifsUnitairesDelegations" inverse="true"
table="MODIF_UNITAIRE_DELEGATION" cascade="all,delete-orphan">
<key on-delete="cascade">
<column name="NUMERO_DEMANDE" precision="10" scale="0" not-null="true" />
</key>
<one-to-many class="ModifUnitaireDelegationVO" />
</set>
[...]
Child Table :
Code:
[...]
<many-to-one name="demande" column="NUMERO_DEMANDE" foreign-key="FK_DELEGATION_DEMANDE"
unique-key="UK_MODIF_DELEGATION" not-null="true" cascade="delete"
class="DemandeModifTitulaireVO" />
[...]
In the java code, it's a simple 'delete' from my DAO.
Is it a problem about the order of the deletion ? Did I forget something into the mappings ? I really don't understand this issue…