DataNucleus JIRA is now in read-only mode. Raise any new issues in GitHub against the plugin that it applies to. DataNucleus JIRA will remain for the foreseeable future but will eventually be discontinued
Issue Details (XML | Word | Printable)

Key: NUCCORE-676
Type: Bug Bug
Status: Closed Closed
Resolution: Cannot Reproduce
Priority: Testcase Required Testcase Required
Assignee: Unassigned
Reporter: fitas amine
Votes: 0
Watchers: 0
Operations

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

can not delete a dependant Objects

Created: 11/Mar/11 10:37 AM   Updated: 01/Apr/11 03:24 PM   Resolved: 12/Mar/11 03:08 PM
Component/s: None
Affects Version/s: None
Fix Version/s: 3.0.0.m3

File Attachments: 1. Zip Archive JDODependantObjects.zip (3 kB)
2. Zip Archive JDODependantObjects.zip (11 kB)


Datastore: MySQL
Severity: Production


 Description  « Hide
When having the following scenario, deleting an instance of A fails with a foreign-key-constraint-violation:

public class A {
  @PrimaryKey
  private String organisationID;
  @PrimaryKey
  private long aID;

  @Persistent(nullValue=NullValue.EXCEPTION, dependent="true")
  private B b;
}

public class B {
  @PrimaryKey
  private String organisationID;
  @PrimaryKey
  private long aID; // using same ID as A because it's directly dependent
}

The problem seems to be that the dependent-attribute in class "A" for field "b" is processed too early, when the A instance is still in the database and referencing the B instance.


the following exceptions happens

vax.jdo.JDODataStoreException: Delete of object "org.datanucleus.test.A@192a848" using statement "DELETE FROM `A` WHERE `AID`=?" failed : Cannot delete or update a parent row: a foreign key constraint fails (`datanucleus/a`, CONSTRAINT `A_FK1` FOREIGN KEY (`B_AID_OID`) REFERENCES `b` (`AID`))
at org.datanucleus.jdo.NucleusJDOHelper.getJDOExceptionForNucleusException(NucleusJDOHelper.java:319)
at org.datanucleus.jdo.JDOPersistenceManager.jdoDeletePersistent(JDOPersistenceManager.java:736)
at org.datanucleus.jdo.JDOPersistenceManager.deletePersistent(JDOPersistenceManager.java:749)
at org.datanucleus.test.Main.main(Main.java:58)
NestedThrowablesStackTrace:
java.sql.BatchUpdateException: Cannot delete or update a parent row: a foreign key constraint fails (`datanucleus/a`, CONSTRAINT `A_FK1` FOREIGN KEY (`B_AID_OID`) REFERENCES `b` (`AID`))
at com.mysql.jdbc.PreparedStatement.executeBatchSerially(PreparedStatement.java:1693)
at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:1108)
at org.datanucleus.store.rdbms.SQLController.processConnectionStatement(SQLController.java:579)
at org.datanucleus.store.rdbms.SQLController.getStatementForUpdate(SQLController.java:202)
at org.datanucleus.store.rdbms.request.DeleteRequest.execute(DeleteRequest.java:216)
at org.datanucleus.store.rdbms.RDBMSPersistenceHandler.deleteTable(RDBMSPersistenceHandler.java:444)
at org.datanucleus.store.rdbms.RDBMSPersistenceHandler.deleteObject(RDBMSPersistenceHandler.java:413)
at org.datanucleus.jdo.state.JDOStateManagerImpl.internalDeletePersistent(JDOStateManagerImpl.java:4320)
at org.datanucleus.jdo.state.JDOStateManagerImpl.deletePersistent(JDOStateManagerImpl.java:4279)
at org.datanucleus.ObjectManagerImpl.deleteObjectInternal(ObjectManagerImpl.java:1633)
at org.datanucleus.ObjectManagerImpl.deleteObject(ObjectManagerImpl.java:1549)
at org.datanucleus.jdo.JDOPersistenceManager.jdoDeletePersistent(JDOPersistenceManager.java:731)
at org.datanucleus.jdo.JDOPersistenceManager.deletePersistent(JDOPersistenceManager.java:749)
at org.datanucleus.test.Main.main(Main.java:58)


public class B {
  @PrimaryKey
  private String organisationID;
  @PrimaryKey
  private long aID; // using same ID as A because it's directly dependent
}

The problem seems to be that the dependent-attribute in class "A" for field "b" is processed too early, when the A instance is still in the database and referencing the B instance.


fitas amine made changes - 11/Mar/11 10:39 AM
Field Original Value New Value
Attachment JDODependantObjects.zip [ 11381 ]
fitas amine added a comment - 11/Mar/11 10:41 AM

fitas amine added a comment - 11/Mar/11 10:43 AM
a temporary workaround, I introduced the method NLJDOHelper.deleteAfterPrimaryObjectDeleted(...). It can be easily used in the above example like this:

public class A
implements DeleteCallback
{
  @PrimaryKey
  private String organisationID;
  @PrimaryKey
  private long aID;

  // TODO DataNucleus WORKAROUND: Omitted 'dependent' due to this
  // issue: https://www.jfire.org/modules/bugs/view.php?id=1330 [^]
  @Persistent(nullValue=NullValue.EXCEPTION) //, dependent="true")
  private B b;

  @Override
  public void jdoPreDelete() {
    NLJDOHelper.deleteAfterPrimaryObjectDeleted(this, b);
  }
}

Andy Jefferson added a comment - 12/Mar/11 02:24 PM
No java files means no testcase. Replace class files with java files

Andy Jefferson made changes - 12/Mar/11 02:24 PM
Priority Major [ 3 ] Incomplete [ 6 ]
fitas amine made changes - 12/Mar/11 02:54 PM
Attachment JDODependantObjects.zip [ 11382 ]
Andy Jefferson added a comment - 12/Mar/11 03:08 PM
I use SVN trunk and using that shows no problem. Since you don't say what version you're using then nothing to do. Here's the log

14:06:39,053 (org.datanucleus.test.Main.main()) WARN [DataNucleus.Datastore.Persist] - >> Delete of org.datanucleus.test.A@1af9e98 needs d
elete of related object at org.datanucleus.test.A.b but cannot delete it direct since FK is here
14:06:39,054 (org.datanucleus.test.Main.main()) DEBUG [DataNucleus.Connection] - Connection found in the pool : [org.datanucleus.store.rdbm
s.ConnectionFactoryImpl$ManagedConnectionImpl@8d5aad, jdbc:hsqldb:mem:nucleus, UserName=SA, HSQL Database Engine Driver] for key=org.datanu
cleus.ObjectManagerImpl@831a91 in factory=ConnectionFactory:tx[org.datanucleus.store.rdbms.ConnectionFactoryImpl@19c9f16]
14:06:39,054 (org.datanucleus.test.Main.main()) DEBUG [DataNucleus.Datastore.Retrieve] - Retrieving PreparedStatement for connection "jdbc:
hsqldb:mem:nucleus, UserName=SA, HSQL Database Engine Driver"
14:06:39,054 (org.datanucleus.test.Main.main()) DEBUG [DataNucleus.Datastore.Native] - DELETE FROM A WHERE AID=<5792337027423620006>
14:06:39,055 (org.datanucleus.test.Main.main()) DEBUG [DataNucleus.Datastore.Persist] - Execution Time = 1 ms (number of rows = 1)
14:06:39,055 (org.datanucleus.test.Main.main()) DEBUG [DataNucleus.Persistence] - Deleting object from persistence : "org.datanucleus.test.B@14af9f7"
14:06:39,055 (org.datanucleus.test.Main.main()) DEBUG [DataNucleus.Lifecycle] - Object "org.datanucleus.test.B@14af9f7" (id="org.datanucleus.test.B:5792337027423620006") has a lifecycle change : "HOLLOW"->"P_DELETED"
14:06:39,055 (org.datanucleus.test.Main.main()) DEBUG [DataNucleus.Transaction] - Object "org.datanucleus.test.B@14af9f7" (id="5792337027423620006") enlisted in transactional cache
14:06:39,055 (org.datanucleus.test.Main.main()) DEBUG [DataNucleus.Persistence] - Object "org.datanucleus.test.B@14af9f7" being deleted from table "B"
14:06:39,056 (org.datanucleus.test.Main.main()) DEBUG [DataNucleus.Connection] - Connection found in the pool : [org.datanucleus.store.rdbms.ConnectionFactoryImpl$ManagedConnectionImpl@8d5aad, jdbc:hsqldb:mem:nucleus, UserName=SA, HSQL Database Engine Driver] for key=org.datanucleus.ObjectManagerImpl@831a91 in factory=ConnectionFactory:tx[org.datanucleus.store.rdbms.ConnectionFactoryImpl@19c9f16]
14:06:39,056 (org.datanucleus.test.Main.main()) DEBUG [DataNucleus.Datastore.Retrieve] - Retrieving PreparedStatement for connection "jdbc:hsqldb:mem:nucleus, UserName=SA, HSQL Database Engine Driver"
14:06:39,056 (org.datanucleus.test.Main.main()) DEBUG [DataNucleus.Datastore.Native] - DELETE FROM B WHERE AID=<5792337027423620006>
14:06:39,056 (org.datanucleus.test.Main.main()) DEBUG [DataNucleus.Datastore.Persist] - Execution Time = 0 ms (number of rows = 1)

so it deletes A first, then B

Andy Jefferson made changes - 12/Mar/11 03:08 PM
Status Open [ 1 ] Resolved [ 5 ]
Fix Version/s 3.0.0.m3 [ 11188 ]
Resolution Cannot Reproduce [ 5 ]
Andy Jefferson made changes - 01/Apr/11 03:24 PM
Status Resolved [ 5 ] Closed [ 6 ]