Referential integrity violation on removal of subtree

Description

Starting with hibernate-core 4.2.7 there is an issue with updating the contents of the DB given the following tree structure:

TopLevel [1] <> [0..1] LeafA [1] <> [*] LeafB

Where the TopLevel is the top level element to access the aggregate structure. It can reference zero or one LeafA object. LeafA is a composite which can contain zero or multiple LeafB objects. All relationships are bidirectional.

Previous to hibernate-core 4.2.7 it was possible to remove the association from TopLevel to LeafA (by just setting the corresponding objects to null at the corresponding ends of the association) which led to the deletion of the entire subtree (LeafA <->* LeafB) from the DB. From hibernate-core 4.2.7 and up hibernate tries to delete only the LeafA entity without deleting the associated LeafB objects. This leads to a referntial integrity violation thrown by the DB.

The attached zip file contains a complete working Maven project to reproduce the issue. Just change the hibernate-core dependency to version above 4.2.6 and the issue described above will raise.

Here is the resulting stack trace as well:
javax.persistence.RollbackException: Error while committing the transaction
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:92)
at com.example.AggregateTest.executeInTransaction(AggregateTest.java:62)
at com.example.AggregateTest.testTopLevelObjectCreationAndMidLevelAggregateRemoval(AggregateTest.java:252)
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.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1387)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1310)
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:80)
... 28 more
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:129)
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:136)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3360)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3560)
at org.hibernate.action.internal.EntityDeleteAction.execute(EntityDeleteAction.java:102)
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:393)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:385)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:300)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:339)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1240)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:404)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175)
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:75)
... 28 more
Caused by: org.h2.jdbc.JdbcSQLException: Referential integrity constraint violation: "FK_QOIW1SGTYIQDFUN53S5BJIP5S: PUBLIC.ABSTRACTAGGREGATE FOREIGN KEY(PARENT_ID) REFERENCES PUBLIC.ABSTRACTAGGREGATE(ID) (8)"
Referential integrity constraint violation: "FK_QOIW1SGTYIQDFUN53S5BJIP5S: PUBLIC.ABSTRACTAGGREGATE FOREIGN KEY(PARENT_ID) REFERENCES PUBLIC.ABSTRACTAGGREGATE(ID) (8)"; SQL statement:
delete from AbstractAggregate where ID=? and VERSION=? [23503-182]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
at org.h2.message.DbException.get(DbException.java:179)
at org.h2.message.DbException.get(DbException.java:155)
at org.h2.constraint.ConstraintReferential.checkRow(ConstraintReferential.java:426)
at org.h2.constraint.ConstraintReferential.checkRowRefTable(ConstraintReferential.java:443)
at org.h2.constraint.ConstraintReferential.checkRow(ConstraintReferential.java:318)
at org.h2.table.Table.fireConstraints(Table.java:908)
at org.h2.table.Table.fireAfterRow(Table.java:926)
at org.h2.command.dml.Delete.update(Delete.java:100)
at org.h2.command.CommandContainer.update(CommandContainer.java:78)
at org.h2.command.Command.executeUpdate(Command.java:254)
at org.h2.jdbc.JdbcPreparedStatement.executeUpdateInternal(JdbcPreparedStatement.java:157)
at org.h2.jdbc.JdbcPreparedStatement.executeUpdate(JdbcPreparedStatement.java:143)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:133)
... 41 more

Environment

None

Activity

Show:
Dimitrij Drus
October 23, 2014, 1:18 PM

Context: I've encountered this Issue during the migration from JBoss EAP 6.0 to JBoss EAP 6.3, which includes hibernate 4.2.14.

Dimitrij Drus
November 3, 2014, 8:21 AM

Since I do not see any special fields for test case description or to upload a dedicated test, I would like to point out that the attached zip file does already contain a simple maven project including JUnit tests requered to reproduce the bug.

Brett Meyer
April 22, 2015, 9:14 PM

Closing rejected issues.

Assignee

Gail Badner

Reporter

Dimitrij Drus

Fix versions

None

Labels

None

backPortable

None

Suitable for new contributors

None

Requires Release Note

None

Pull Request

None

backportDecision

None

Components

Affects versions

Priority

Major
Configure