| Summary: | [DB] ClassCastException after setBranch when server cache contains partially loaded collections | ||
|---|---|---|---|
| Product: | [Modeling] EMF | Reporter: | Stefan Winkler <stefan> |
| Component: | cdo.db | Assignee: | Eike Stepper <stepper> |
| Status: | CLOSED FIXED | QA Contact: | Eike Stepper <stepper> |
| Severity: | normal | ||
| Priority: | P2 | ||
| Version: | 4.1 | ||
| Target Milestone: | --- | ||
| Hardware: | All | ||
| OS: | All | ||
| Whiteboard: | |||
Testcase contained in commit b7e8c99d19db29a9a116e657faf890109515608f Author: Stefan Winkler <stefan@winklerweb.net> 2012-01-25 13:03:37 Committer: Stefan Winkler <stefan@winklerweb.net> 2012-01-25 13:05:16 Parent: bf4a6bfcbf48c59a10e115e5eb48a2344bf2a0ec (Add a missing if(TRACER.isEnabled()) line) Branches: origin/bugs/369646, bugs/369646 [369646] [DB] ClassCastException after setBranch https://bugs.eclipse.org/bugs/show_bug.cgi?id=369646 The bug is caused by a revision of which the lists are not fully loaded (e.g., because of partial collection loading). If such an object is contained in the server's revision cache, switchViewTarget (the server-side operation of setBranch) will cause a ClassCastException. The problem is most likely not DB-specific, but a general core bug. The test case passes here: commit 3629bad6bcc17723ba9bbfc4249e2abac3686244 I suspect a duplicate of bug 337587. *** This bug has been marked as a duplicate of bug 337587 *** Sorry, with H2 the test does fail. Investigating further... Three observations: 1) The test case does not use PCL. 2) The test case has never failed outside the H2 suites. 3) The test case reproducibly fails in the H2 branching-with-ranges suites. Moving back to cdo.db. Stefan, please have a look... BTW. this is somewhat urgent because the Hudson suite is affected. Ok, as discussed on Skype, here's what I did: 1. merged the current master into bugs/369646 to make it current 2. added a second test case showing a branch switch with PCL 3. added a condition to the check for incomplete revisions in RevisionDeltaImpl 4. provided a fix for the bug by ensuring that both oldRevision and newRevision are fully loaded before creating the ResourceDeltas Re 2.: Both test cases fail with DBStore, but not with MEMStore. I then put a breakpoint in the MEMStoreChunkReader to check if it is called: it actually is not. So I guess the MEMStore does not really do PCL nor simulate it somehow. It just fulfills the API, or so it seems ... Re 3.: Eike, I think the ElementProxy is the client-side representation in the list (as you said, to track moves of elements). The CDOListImpl.UNINITIALIZED seems to be the server-side representation to mark the fact, that the element at this position has not been loaded. So I added the check for the latter (then I get the more correct exception that PCL is not supported with the testcases) Re 4: As discussed, I added calls to Repository.ensureChunks() for both revisions in View.changeViewTarget. This makes the test cases pass. Please check out the result in the branch. I'm assigning you again to check, if the solution (4.) is acceptable for now. If so, please go ahead and merge into master. commit 7698f3a56562e5e538ce5584e427ada9390b9e87 Author: Stefan Winkler <stefan@winklerweb.net> 2012-04-29 15:02:21 Committer: Stefan Winkler <stefan@winklerweb.net> 2012-04-29 15:02:21 Parent: d58f2f8c74651fd147568141314eb4df614e60fa ([369646] [DB] ClassCastException after setBranch when server cache contains partially loaded collections https://bugs.eclipse.org/bugs/show_bug.cgi?id=369646) Branches: bugs/369646, origin/bugs/369646 [369646] [DB] ClassCastException after setBranch when server cache contains partially loaded collections https://bugs.eclipse.org/bugs/show_bug.cgi?id=369646 Proposed fix for bug: ensure that both revisions are fully loaded, before doing the compare. (makes branch switching slower, but handles PCL correctly) I applied an optimization. In the new BaseCDORevision.flags I now maintain an UNCHUNKED flag to bypass CDOElementProxy resolution whenever it's not needed (anymore). commit 442b3dee3931d65fba39842912584ef8cb0215f9 Closing. |
The following code fails at the last line: // set up a resource with 1 object as content CDOSession session = openSession(); CDOTransaction transaction = session.openTransaction(); CDOResource res = transaction.createResource(getResourcePath("/test")); Category c = getModel1Factory().createCategory(); c.setName("Test"); res.getContents().add(c); transaction.commit(); // create two cascading branches CDOBranch sub1 = transaction.getBranch().createBranch("sub1"); CDOBranch sub2 = sub1.createBranch("sub2"); // now delete the contents in the sub2 branch transaction.setBranch(sub2); res.getContents().remove(0); transaction.commit(); // and now try to switch the transaction to the parent branch transaction.setBranch(sub1); The exception is: org.eclipse.net4j.signal.RemoteException: java.lang.ClassCastException: org.eclipse.emf.cdo.common.revision.CDORevisionUtil$Uninitialized cannot be cast to org.eclipse.emf.cdo.common.id.CDOID at org.eclipse.net4j.signal.RequestWithConfirmation.getRemoteException(RequestWithConfirmation.java:139) at org.eclipse.net4j.signal.RequestWithConfirmation.setRemoteException(RequestWithConfirmation.java:128) at org.eclipse.net4j.signal.SignalProtocol.handleRemoteException(SignalProtocol.java:460) at org.eclipse.net4j.signal.RemoteExceptionIndication.indicating(RemoteExceptionIndication.java:63) at org.eclipse.net4j.signal.Indication.doExtendedInput(Indication.java:55) at org.eclipse.net4j.signal.Signal.doInput(Signal.java:326) at org.eclipse.net4j.signal.Indication.execute(Indication.java:49) at org.eclipse.net4j.signal.Signal.runSync(Signal.java:251) at org.eclipse.net4j.signal.Signal.run(Signal.java:147) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:680) Caused by: java.lang.ClassCastException: org.eclipse.emf.cdo.common.revision.CDORevisionUtil$Uninitialized cannot be cast to org.eclipse.emf.cdo.common.id.CDOID at org.eclipse.emf.cdo.internal.server.Session.provideCDOID(Session.java:352) at org.eclipse.emf.cdo.internal.common.revision.delta.CDOSingleValueFeatureDeltaImpl.writeValue(CDOSingleValueFeatureDeltaImpl.java:86) at org.eclipse.emf.cdo.internal.common.revision.delta.CDOSingleValueFeatureDeltaImpl.write(CDOSingleValueFeatureDeltaImpl.java:62) at org.eclipse.emf.cdo.internal.common.protocol.CDODataOutputImpl.writeCDOFeatureDelta(CDODataOutputImpl.java:495) at org.eclipse.emf.cdo.internal.common.revision.delta.CDOListFeatureDeltaImpl.write(CDOListFeatureDeltaImpl.java:136) at org.eclipse.emf.cdo.internal.common.protocol.CDODataOutputImpl.writeCDOFeatureDelta(CDODataOutputImpl.java:495) at org.eclipse.emf.cdo.internal.common.revision.delta.CDORevisionDeltaImpl.write(CDORevisionDeltaImpl.java:168) at org.eclipse.emf.cdo.internal.common.protocol.CDODataOutputImpl.writeCDORevisionDelta(CDODataOutputImpl.java:490) at org.eclipse.emf.cdo.server.internal.net4j.protocol.SwitchTargetIndication.responding(SwitchTargetIndication.java:84) at org.eclipse.emf.cdo.server.internal.net4j.protocol.CDOServerIndicationWithMonitoring.responding(CDOServerIndicationWithMonitoring.java:170) at org.eclipse.net4j.signal.IndicationWithMonitoring.responding(IndicationWithMonitoring.java:90) at org.eclipse.net4j.signal.IndicationWithResponse.doExtendedOutput(IndicationWithResponse.java:96) at org.eclipse.net4j.signal.Signal.doOutput(Signal.java:296) at org.eclipse.net4j.signal.IndicationWithResponse.execute(IndicationWithResponse.java:65) at org.eclipse.net4j.signal.IndicationWithMonitoring.execute(IndicationWithMonitoring.java:63) at org.eclipse.emf.cdo.server.internal.net4j.protocol.CDOServerReadIndicationWithMonitoring.execute(CDOServerReadIndicationWithMonitoring.java:36) ... 5 more