Here's an interesting situation I'm debugging now for Cayenne 1.1.
It seems to be related to CAY-213 "NullPointerException in
ContextCommit with locking". I suspect that it's true of 1.2 and
could very well be true for 3.0 as well, although I don't have that
handy to test with.
http://issues.apache.org/cayenne/browse/CAY-213
My testing seems to reveal that the same problem occurs when you set a
to-one relationship to null. Line 291 in removeToManyTarget() sets
the state of the previous to-one relationship object to MODIFIED, but
doesn't retain a snapshot for that object.
Here's some simple test code that shows the problem. And switching
the scalar setter with the relationship setter works around the
problem.
It seems to me that the the fix is to add
dataContext.getObjectStore().retainSnapshot(this);
as was done for writeProperty().
public void run() throws Exception
{
initCayenne("cayenne.xml");
// Set up database
createSchemaForObjEntityName(Configuration.getSharedConfiguration(),
"PotentialCustomer");
DataContext dc = DataContext.createDataContext();
// Set up test data
PotentialCustomer pc =
(PotentialCustomer)dc.createAndRegisterNewObject(PotentialCustomer.class);
Premise premise = (Premise)dc.createAndRegisterNewObject(Premise.class);
pc.setToOneTarget("premise", premise, true);
dc.commitChanges();
// Force failure:
pc.setToOneTarget("premise", null, true);
premise.writeProperty("altitude", new Integer(0));
// On commitChanges(), no snapshot available for building locking
// java.lang.NullPointerException
// at org.objectstyle.cayenne.access.ContextCommit.appendOptimisticLockingAttributes(ContextCommit.java:564)
dc.commitChanges();
}
java.lang.NullPointerException
at org.objectstyle.cayenne.access.ContextCommit.appendOptimisticLockingAttributes(ContextCommit.java:564)
at org.objectstyle.cayenne.access.ContextCommit.prepareUpdateQueries(ContextCommit.java:426)
at org.objectstyle.cayenne.access.ContextCommit.commit(ContextCommit.java:156)
at org.objectstyle.cayenne.access.DataContext.commitChanges(DataContext.java:1266)
at org.objectstyle.cayenne.access.DataContext.commitChanges(DataContext.java:1236)
at com.gvea.cayenne.TestOptimisticLockingFailureOnSingleTargetNull.run(TestOptimisticLockingFailureOnSingleTargetNull.java:110)
at com.gvea.cayenne.TestOptimisticLockingFailureOnSingleTargetNull.main(TestOptimisticLockingFailureOnSingleTargetNull.java:24)
Note that some of these line numbers may vary as my version of Cayenne
1.1 has local mods.
This archive was generated by hypermail 2.0.0 : Thu Mar 27 2008 - 15:34:06 EDT