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
|