Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 320837 - [Legacy] Legacy fails when loading a contained object before its container
Summary: [Legacy] Legacy fails when loading a contained object before its container
Status: CLOSED FIXED
Alias: None
Product: EMF
Classification: Modeling
Component: cdo.legacy (show other bugs)
Version: 4.0   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Martin Fluegge CLA
QA Contact: Eike Stepper CLA
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-07-25 04:44 EDT by Martin Fluegge CLA
Modified: 2012-06-19 07:08 EDT (History)
0 users

See Also:
stepper: review+


Attachments
Test v1 (2.69 KB, patch)
2010-07-25 09:19 EDT, Martin Fluegge CLA
no flags Details | Diff
Patch v1 (1.96 KB, patch)
2010-07-25 10:31 EDT, Martin Fluegge CLA
no flags Details | Diff
Test+Fix v2 - ready to be committed (5.28 KB, patch)
2010-07-25 11:57 EDT, Eike Stepper CLA
no flags Details | Diff
Test+Fix v3 - ready to be committed (8.62 KB, patch)
2010-07-25 12:25 EDT, Eike Stepper CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Fluegge CLA 2010-07-25 04:44:14 EDT
When loading a contained object before ist container legacy crashes with the following exception:


java.lang.IllegalStateException: Failing event PREPARE in state CLEAN for CDOLegacyWrapper[OID3, org.eclipse.emf.cdo.tests.legacy.model4.impl.ContainedElementNoOppositeImpl] (data=Pair[CDOTransaction[3:1], []])
	at org.eclipse.net4j.util.fsm.FiniteStateMachine.process(FiniteStateMachine.java:153)
	at org.eclipse.emf.internal.cdo.CDOStateMachine.prepare(CDOStateMachine.java:229)
	at org.eclipse.emf.internal.cdo.CDOStateMachine.attach(CDOStateMachine.java:191)
	at org.eclipse.emf.cdo.eresource.impl.CDOResourceImpl.attached(CDOResourceImpl.java:827)
	at org.eclipse.emf.cdo.eresource.impl.CDOResourceImpl.attached(CDOResourceImpl.java:818)
	at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eBasicSetContainer(BasicEObjectImpl.java:1342)
	at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eInverseAdd(BasicEObjectImpl.java:1423)
	at org.eclipse.emf.cdo.tests.legacy.model4.impl.RefSingleContainedNPLImpl.setElement(RefSingleContainedNPLImpl.java:121)
	at org.eclipse.emf.cdo.tests.legacy.model4.impl.RefSingleContainedNPLImpl.eSet(RefSingleContainedNPLImpl.java:180)
	at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eSet(BasicEObjectImpl.java:1081)
	at org.eclipse.emf.internal.cdo.CDOLegacyWrapper.revisionToInstanceFeature(CDOLegacyWrapper.java:554)
	at org.eclipse.emf.internal.cdo.CDOLegacyWrapper.revisionToInstance(CDOLegacyWrapper.java:423)
	at org.eclipse.emf.internal.cdo.CDOLegacyWrapper.cdoInternalPostLoad(CDOLegacyWrapper.java:298)
	at org.eclipse.emf.internal.cdo.view.CDOViewImpl.cleanObject(CDOViewImpl.java:1179)
	at org.eclipse.emf.internal.cdo.view.CDOViewImpl.createObject(CDOViewImpl.java:1130)
	at org.eclipse.emf.internal.cdo.view.CDOViewImpl.getObject(CDOViewImpl.java:1005)
	at org.eclipse.emf.internal.cdo.transaction.CDOTransactionImpl.getObject(CDOTransactionImpl.java:878)
	at org.eclipse.emf.internal.cdo.transaction.CDOTransactionImpl.getObject(CDOTransactionImpl.java:1)
	at org.eclipse.emf.internal.cdo.CDOLegacyWrapper.getEObjectFromPotentialID(CDOLegacyWrapper.java:796)
	at org.eclipse.emf.internal.cdo.CDOLegacyWrapper.revisionToInstanceContainment(CDOLegacyWrapper.java:456)
	at org.eclipse.emf.internal.cdo.CDOLegacyWrapper.revisionToInstance(CDOLegacyWrapper.java:419)
	at org.eclipse.emf.internal.cdo.CDOLegacyWrapper.cdoInternalPostLoad(CDOLegacyWrapper.java:298)
	at org.eclipse.emf.internal.cdo.view.CDOViewImpl.cleanObject(CDOViewImpl.java:1179)
	at org.eclipse.emf.internal.cdo.view.CDOViewImpl.createObject(CDOViewImpl.java:1130)
	at org.eclipse.emf.internal.cdo.view.CDOViewImpl.getObject(CDOViewImpl.java:1005)
	at org.eclipse.emf.internal.cdo.transaction.CDOTransactionImpl.getObject(CDOTransactionImpl.java:878)
	at org.eclipse.emf.internal.cdo.view.CDOViewImpl.getObject(CDOViewImpl.java:1048)
	at org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_320690_Tests.testLockRefTargets(Bugzilla_320690_Tests.java:60)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:585)
	at junit.framework.TestCase.runTest(TestCase.java:168)
	at org.eclipse.net4j.util.tests.AbstractOMTest.runBare(AbstractOMTest.java:150)
	at org.eclipse.emf.cdo.tests.config.impl.ConfigTest.runBare(ConfigTest.java:422)
	at junit.framework.TestResult$1.protect(TestResult.java:110)
	at junit.framework.TestResult.runProtected(TestResult.java:128)
	at junit.framework.TestResult.run(TestResult.java:113)
	at junit.framework.TestCase.run(TestCase.java:124)
	at org.eclipse.net4j.util.tests.AbstractOMTest.run(AbstractOMTest.java:196)
	at junit.framework.TestSuite.runTest(TestSuite.java:232)
	at org.eclipse.emf.cdo.tests.config.impl.ConfigTestSuite$TestWrapper.runTest(ConfigTestSuite.java:126)
	at junit.framework.TestSuite.run(TestSuite.java:227)
	at junit.framework.TestSuite.runTest(TestSuite.java:232)
	at junit.framework.TestSuite.run(TestSuite.java:227)
	at junit.framework.TestSuite.runTest(TestSuite.java:232)
	at junit.framework.TestSuite.run(TestSuite.java:227)
	at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:83)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)


I ran through the problem and it seems that the caus of the problem can be described as follows:

If the contained element is loaded, the wrapper will be created by CDO, set to state CLEAN and afterwards cdoInternalPostLoad() will be called which sets the information from the revision to the instance. 

Thereby the container of the element is set. This lead to a creation of the container object, which itself transforms the revision data to its instance. This leads to setting the contained object to its related feature in the container.

At this point the contained elements resource is null wherefore it will be attached to the containers resource (BasicEObjectImpl, 1342). This results in attaching the object to the CDOResource and processing an ATTACH operation in the CDOStateMachine. Remember that the contained object which should be attached to the resource it already in state CLEAN. So, the state machine denies preparing it. 

This does not happen if the container is loaded before, because the contained object will be created during the containers creation.
Comment 1 Martin Fluegge CLA 2010-07-25 09:19:48 EDT
Created attachment 175174 [details]
Test v1

Here is a small test to reproduce the problem.
Comment 2 Martin Fluegge CLA 2010-07-25 10:31:06 EDT
Created attachment 175176 [details]
Patch v1

Split seconds before my head was going to explode I found the solution. 

Feels like I have an unlimited number of containment cycles in my head. 

Here is the patch?

And now it?s Time for a nap ;)
Comment 3 Eike Stepper CLA 2010-07-25 11:57:19 EDT
Created attachment 175177 [details]
Test+Fix v2 - ready to be committed
Comment 4 Eike Stepper CLA 2010-07-25 12:25:20 EDT
Created attachment 175178 [details]
Test+Fix v3 - ready to be committed
Comment 5 Martin Fluegge CLA 2010-07-25 13:06:49 EDT
Committed to HEAD.
Comment 6 Eike Stepper CLA 2011-06-23 03:41:52 EDT
Available in R20110608-1407