So, I was testing the 7/7 nightly build to see how the fix for
CAY-585
worked, and I've come across a new issue. I wondered if it was
due to
the fix, :), so I've gone back and tested against nightly build
7/5 and
also 1.2RC2, and the problem still exists (so, not from the
CAY-585 fix,
apparently). I wasn't sure whether to tag it onto the end of
CAY-585 or
not. In any event, you can use the exact same mapping as in
CAY-585 to
reproduce the error. Add the following line to the setUp method:
dc.performGenericQuery(new SQLTemplate(Assignment.class, "delete
from
AssignmentTransaction"));
And then add the following test case:
public void testCayenneFaultCaseBaseObjectNewContext() {
DataContext dc = DataContext.createDataContext();
Assignment a = (Assignment)
DataObjectUtils.objectForPK(dc,Assignment.class,1);
AssignmentTransaction at = (AssignmentTransaction)
dc.createAndRegisterNewObject(AssignmentTransaction.class);
at.setAssignment(a);
dc.commitChanges();
dc = DataContext.createDataContext();
a = (Assignment) DataObjectUtils.objectForPK
(dc,Assignment.class,1);
at = (AssignmentTransaction) a.getTransactions().get(0);
at.setStartTime(new Date());
at.getAssignment().getTitle();
}
This will produce a fault failure exception attempting to resolve
the
object for: <Objectid:Assignmentid:1>.
I also played with the following test case, which produces no
exception.
public void
testCayenneFaultCaseBaseObjectNewContextCleanTransactionFetch() {
DataContext dc = DataContext.createDataContext();
Assignment a = (Assignment)
DataObjectUtils.objectForPK(dc,Assignment.class,1);
AssignmentTransaction at = (AssignmentTransaction)
dc.createAndRegisterNewObject(AssignmentTransaction.class);
at.setAssignment(a);
dc.commitChanges();
int atpk = DataObjectUtils.intPKForObject(at);
dc = DataContext.createDataContext();
a = (Assignment) DataObjectUtils.objectForPK
(dc,Assignment.class,1);
at = (AssignmentTransaction)
DataObjectUtils.objectForPK(dc,AssignmentTransaction.class,atpk);
at.setStartTime(new Date());
at.getAssignment().getTitle();
}
A few notes: The exception only occurs if you snag the
transaction from
the re-fetched assignment (a.getTransactions()), and it only
occurs if
you modify the transaction so fetched (at.setStartTime).
Interestingly,
before the call to at.setStartTime(new Date()), at.getAssignment
() works
fine, and a printout of the persistence state showed it as
committed;
after the call to setStartTime, at.getAssignment
().getPersistentState
shows it in state committed. This is not the case for the non-
exception
producing test case.
Also, turning off the shared cache gets rid of the error. Also, it
does, in fact, matter that the AssignmentTransaction was already
loaded,
but doesn't seem to matter exactly how it got loaded. For
instance, the
following test case also produces an exception:
public void
testCayenneFaultCaseBaseObjectNewContextPriorTransaction() {
DataContext dc = DataContext.createDataContext();
dc.performGenericQuery(new SQLTemplate(Assignment.class,
"INSERT
into AssignmentTransaction (assignmentid,id) VALUES (1,1)"));
Assignment a = (Assignment)
DataObjectUtils.objectForPK(dc,Assignment.class,1);
AssignmentTransaction at;
a.getTransactions().size();//.size forces the assignment
transaction above to be faulted...
dc = DataContext.createDataContext();
a = (Assignment) DataObjectUtils.objectForPK
(dc,Assignment.class,1);
at = (AssignmentTransaction) a.getTransactions().get(0);
at.setStartTime(new Date());
at.getAssignment().getTitle();
}
If you comment out the a.getTransactions().size() line, no exception
will be produced (and the at.setStartTime does /not/ cause the
assignment associated with at.getAssignment to wind up HOLLOW).
Robert