Issue Details (XML | Word | Printable)

Key: NUCCORE-12
Type: Bug Bug
Status: Closed Closed
Resolution: Cannot Reproduce
Priority: Major Major
Assignee: Unassigned
Reporter: Karl M. Davis
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
DataNucleus Core

Unable to delete JDO instances when PK includes a dependent field

Created: 12/May/08 01:35 AM   Updated: 10/Dec/10 07:48 AM   Resolved: 28/Nov/10 02:43 PM
Component/s: None
Affects Version/s: 1.0.0.m2
Fix Version/s: 2.2.0.release

File Attachments: 1. File dependentPkFkDeletion-model.diff (4 kB)
2. File dependentPkFkDeletion-test.diff (6 kB)

Environment:
* 32bit Linux, Java 1.6, postgresql
* 32bit Linux, Java 1.6, hgsqldb

Forum Thread URL: http://www.jpox.org/servlet/forum/viewthread?thread=5075
Datastore: HSQL, PostgreSQL
Severity: Production


 Description  « Hide
When one of a JDO class' primary key fields is also a dependent key, any instances of that class cannot be deleted. Here's some sample metadata:
<class name="DependentHolder2" detachable="true">

<field name="element" persistence-modifier="persistent" dependent="true" primary-key="true">

<column allows-null="false"/>

<foreign-key/>

</field>

</class>


It seems as if datanucleus tries to delete the dependent element before/in a separate operation than deleting the "holder" object and the datastore throws an exception indicating that the FK constraint has been violated. Here's a sample exception when running against HSQLDB:
javax.jdo.JDOUserException: One or more instances could not be deleted
at org.datanucleus.jdo.JDOPersistenceManager.deletePersistentAll(JDOPersistenceManager.java:806)
at org.datanucleus.tests.TestHelper.clean(TestHelper.java:225)
at org.datanucleus.tests.DependentFieldTest.clearDependentData(DependentFieldTest.java:2430)
at org.datanucleus.tests.DependentFieldTest.testDependentPkFieldsDeletion(DependentFieldTest.java:437)
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:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
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 org.apache.maven.surefire.junit.JUnitTestSet.execute(JUnitTestSet.java:213)
at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:138)
at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:125)
at org.apache.maven.surefire.Surefire.run(Surefire.java:132)
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 org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:290)
at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:818)
NestedThrowablesStackTrace:
javax.jdo.JDODataStoreException: Delete of object "org.jpox.samples.dependentfield.SimpleDependentElement@14c9c62" using statement "DELETE FROM SIMPLEDEPENDENTELEMENT WHERE ID=?" failed : Integrity constraint violation DEPENDENTHOLDER2_FK1 table: DEPENDENTHOLDER2 in statement [DELETE FROM SIMPLEDEPENDENTELEMENT WHERE ID=?]
at org.datanucleus.jdo.NucleusJDOHelper.getJDOExceptionForNucleusException(NucleusJDOHelper.java:289)
at org.datanucleus.jdo.JDOPersistenceManager.jdoDeletePersistent(JDOPersistenceManager.java:756)
at org.datanucleus.jdo.JDOPersistenceManager.deletePersistentAll(JDOPersistenceManager.java:797)
at org.datanucleus.tests.TestHelper.clean(TestHelper.java:225)
at org.datanucleus.tests.DependentFieldTest.clearDependentData(DependentFieldTest.java:2430)
at org.datanucleus.tests.DependentFieldTest.testDependentPkFieldsDeletion(DependentFieldTest.java:437)
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:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
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 org.apache.maven.surefire.junit.JUnitTestSet.execute(JUnitTestSet.java:213)
at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:138)
at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:125)
at org.apache.maven.surefire.Surefire.run(Surefire.java:132)
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 org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:290)
at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:818)
NestedThrowablesStackTrace:
java.sql.SQLException: Integrity constraint violation DEPENDENTHOLDER2_FK1 table: DEPENDENTHOLDER2 in statement [DELETE FROM SIMPLEDEPENDENTELEMENT WHERE ID=?]
at org.hsqldb.jdbc.Util.throwError(Unknown Source)
at org.hsqldb.jdbc.jdbcPreparedStatement.executeUpdate(Unknown Source)
at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:94)
at org.datanucleus.store.rdbms.ParamLoggingPreparedStatement.executeUpdate(ParamLoggingPreparedStatement.java:363)
at org.datanucleus.store.rdbms.SQLController.executeStatementUpdate(SQLController.java:396)
at org.datanucleus.store.rdbms.request.DeleteRequest.execute(DeleteRequest.java:232)
at org.datanucleus.store.rdbms.RDBMSPersistenceHandler.deleteTable(RDBMSPersistenceHandler.java:438)
at org.datanucleus.store.rdbms.RDBMSPersistenceHandler.deleteObject(RDBMSPersistenceHandler.java:411)
at org.datanucleus.state.JDOStateManagerImpl.internalDeletePersistent(JDOStateManagerImpl.java:4027)
at org.datanucleus.state.JDOStateManagerImpl.deletePersistent(JDOStateManagerImpl.java:3996)
at org.datanucleus.ObjectManagerImpl.deleteObjectInternal(ObjectManagerImpl.java:1360)
at org.datanucleus.store.mapped.mapping.PersistenceCapableMapping.preDelete(PersistenceCapableMapping.java:1146)
at org.datanucleus.store.rdbms.request.DeleteRequest.execute(DeleteRequest.java:158)
at org.datanucleus.store.rdbms.RDBMSPersistenceHandler.deleteTable(RDBMSPersistenceHandler.java:438)
at org.datanucleus.store.rdbms.RDBMSPersistenceHandler.deleteObject(RDBMSPersistenceHandler.java:411)
at org.datanucleus.state.JDOStateManagerImpl.internalDeletePersistent(JDOStateManagerImpl.java:4027)
at org.datanucleus.state.JDOStateManagerImpl.deletePersistent(JDOStateManagerImpl.java:3996)
at org.datanucleus.ObjectManagerImpl.deleteObjectInternal(ObjectManagerImpl.java:1360)
at org.datanucleus.ObjectManagerImpl.deleteObject(ObjectManagerImpl.java:1286)
at org.datanucleus.jdo.JDOPersistenceManager.jdoDeletePersistent(JDOPersistenceManager.java:751)
at org.datanucleus.jdo.JDOPersistenceManager.deletePersistentAll(JDOPersistenceManager.java:797)
at org.datanucleus.tests.TestHelper.clean(TestHelper.java:225)
at org.datanucleus.tests.DependentFieldTest.clearDependentData(DependentFieldTest.java:2430)
at org.datanucleus.tests.DependentFieldTest.testDependentPkFieldsDeletion(DependentFieldTest.java:437)
at org.datanucleus.tests.DependentFieldTest.testDependentPkFieldsDeletion(DependentFieldTest.java:437)
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:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
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 org.apache.maven.surefire.junit.JUnitTestSet.execute(JUnitTestSet.java:213)
at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:138)
at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:125)
at org.apache.maven.surefire.Surefire.run(Surefire.java:132)
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 org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:290)
at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:818)

This problem occurs when running against either postgresql or hsqldb (haven't tested other datastores). I have created a testcase that illustrates it that I'll attach to this issue.

Karl M. Davis added a comment - 12/May/08 01:36 AM
This is a patch against test/test.samples/src HEAD that adds two sample model classes.

Karl M. Davis made changes - 12/May/08 01:36 AM
Field Original Value New Value
Attachment dependentPkFkDeletion-model.diff [ 10750 ]
Karl M. Davis added a comment - 12/May/08 01:40 AM
This is a patch against test/test.do.application/src HEAD that adds a new unit test that illustrates the problem described in this issue. Please note that because the model classes in question throw errors in clearDependentData(...), a number of other tests will fail after applying this patch. This could be resolved by creating a separate cleanup method for the two model classes in question.

Karl M. Davis made changes - 12/May/08 01:40 AM
Attachment dependentPkFkDeletion-test.diff [ 10751 ]
Andy Jefferson added a comment - 28/Nov/10 02:43 PM
Added contributed test to SVN (with fix to use own PK classes, as per all docs say for compound identity). Test passes fine with no changes so must have been fixed since 1.x

Andy Jefferson made changes - 28/Nov/10 02:43 PM
Status Open [ 1 ] Resolved [ 5 ]
Fix Version/s 2.2.0.release [ 10931 ]
Resolution Cannot Reproduce [ 5 ]
Andy Jefferson made changes - 10/Dec/10 07:48 AM
Status Resolved [ 5 ] Closed [ 6 ]