Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Cannot Reproduce
-
3.0.2
-
None
Description
Steps to reproduce:
1) Create object A
2) Add child object B (A has a cascade delete rule for B)
3) Create a child context
4) Delete A in the child context
5) commitChangesToParent in the child context
6) NPE:
java.lang.NullPointerException
at org.apache.cayenne.access.DataContextDeleteAction.performDelete(DataContextDeleteAction.java:59)
at org.apache.cayenne.access.DataContext.deleteObject(DataContext.java:946)
at org.apache.cayenne.graph.ChildDiffLoader.nodeRemoved(ChildDiffLoader.java:127)
at org.apache.cayenne.graph.NodeDeleteOperation.apply(NodeDeleteOperation.java:37)
at org.apache.cayenne.graph.CompoundDiff.apply(CompoundDiff.java:91)
at org.apache.cayenne.access.ObjectStoreGraphDiff.apply(ObjectStoreGraphDiff.java:134)
at org.apache.cayenne.access.DataContext.onContextFlush(DataContext.java:1074)
at org.apache.cayenne.BaseContext.onSync(BaseContext.java:298)
at org.apache.cayenne.access.DataContext.flushToParent(DataContext.java:1121)
at org.apache.cayenne.access.DataContext.commitChangesToParent(DataContext.java:1051)
Analysis:
The issue appears to be that the graph diff to be committed to the parent context records that both A and B are to be deleted, however the delete rules for A also cause B to deleted:
1) Child diff causes A to be deleted
2) A's delete rules cause B to deleted
3) Child diff causes B to be deleted, but B no longer exists
Possible fix (not tested in any way):
In ChildDiffLoader.nodeRemoved(), check if the result of findObject() is null before attempting to delete it.
Workaround (works for me):
In the child context, delete B before deleting A.