Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Stepper2012-10-31 09:38:45 -0400
committerEike Stepper2012-10-31 09:38:45 -0400
commitccd00426290e441a0bbfc367ee5558acdd76338d (patch)
tree79a3c7461409aba5207dcfb4c4642420b0122a50
parente51c7bd310ced12d244e9310a435adc024ca9f61 (diff)
downloadcdo-ccd00426290e441a0bbfc367ee5558acdd76338d.tar.gz
cdo-ccd00426290e441a0bbfc367ee5558acdd76338d.tar.xz
cdo-ccd00426290e441a0bbfc367ee5558acdd76338d.zip
[325866] IllegalStateException when committing a reattached containment
of a detached container after branch merge with XRef enabled https://bugs.eclipse.org/bugs/show_bug.cgi?id=325866
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_325866_Test.java68
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java15
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOStateMachine.java100
3 files changed, 129 insertions, 54 deletions
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_325866_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_325866_Test.java
index 04ac3777a6..80e355a2be 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_325866_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_325866_Test.java
@@ -12,12 +12,15 @@
package org.eclipse.emf.cdo.tests.bugzilla;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.server.IRepository;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.tests.AbstractCDOTest;
import org.eclipse.emf.cdo.tests.config.IRepositoryConfig;
+import org.eclipse.emf.cdo.tests.config.impl.RepositoryConfig;
import org.eclipse.emf.cdo.tests.model4.GenRefMultiContained;
+import org.eclipse.emf.cdo.transaction.CDOMerger;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.view.CDOAdapterPolicy;
@@ -98,4 +101,69 @@ public class Bugzilla_325866_Test extends AbstractCDOTest
s1Tr1.commit();
assertEquals(false, s1Tr1.isDirty());
}
+
+ @Requires(RepositoryConfig.CAPABILITY_BRANCHING)
+ public void testXRefReattachBranchLevel2() throws Exception
+ {
+ // setup transaction.
+ final CDOSession session1 = openSession();
+ final CDOTransaction s1Tr1 = session1.openTransaction();
+ s1Tr1.options().addChangeSubscriptionPolicy(CDOAdapterPolicy.ALL);
+
+ // create resource, and container tree using transaction 1.
+ final CDOResource resource = s1Tr1.createResource(getResourcePath("/test1"));
+ GenRefMultiContained container1 = getModel4Factory().createGenRefMultiContained();
+ GenRefMultiContained container2 = getModel4Factory().createGenRefMultiContained();
+ GenRefMultiContained container3 = getModel4Factory().createGenRefMultiContained();
+ GenRefMultiContained container4 = getModel4Factory().createGenRefMultiContained();
+ GenRefMultiContained container5 = getModel4Factory().createGenRefMultiContained();
+ resource.getContents().add(container1);
+ resource.getContents().add(container2);
+ resource.getContents().add(container3);
+ container1.getElements().add(container4);
+ container4.getElements().add(container5);
+
+ s1Tr1.commit();
+ sleep(1000L);
+
+ // setup another branch.
+ final CDOBranch otherBranch = s1Tr1.getBranch().createBranch("other");
+ final CDOTransaction s1Tr3 = session1.openTransaction(otherBranch);
+
+ CDOResource branchResource = s1Tr3.getObject(resource);
+ assertNotSame(null, branchResource);
+
+ GenRefMultiContained otherContainer1 = (GenRefMultiContained)branchResource.getContents().get(0);
+ assertNotSame(null, otherContainer1);
+ GenRefMultiContained otherContainer2 = (GenRefMultiContained)branchResource.getContents().get(1);
+ assertNotSame(null, otherContainer2);
+ GenRefMultiContained otherContainer3 = (GenRefMultiContained)branchResource.getContents().get(2);
+ assertNotSame(null, otherContainer3);
+ GenRefMultiContained otherContainer4 = (GenRefMultiContained)otherContainer1.getElements().get(0);
+ assertNotSame(null, otherContainer4);
+ GenRefMultiContained otherContainer5 = (GenRefMultiContained)otherContainer4.getElements().get(0);
+ assertNotSame(null, otherContainer5);
+
+ // detach the container1 on branch.
+ branchResource.getContents().remove(otherContainer1);
+
+ // re-attach container1 child.
+ otherContainer2.getElements().add(otherContainer4);
+
+ // re-attach container1 child.
+ otherContainer3.getElements().add(otherContainer5);
+
+ s1Tr3.commit();
+ assertEquals(false, s1Tr3.isDirty());
+
+ sleep(1000L);
+
+ // merge the other branch to main.
+ CDOBranchPoint head = s1Tr3.getBranch().getHead();
+ CDOMerger merger = new DefaultCDOMerger.PerFeature.ManyValued();
+ s1Tr1.merge(head, merger);
+
+ s1Tr1.commit();
+ assertEquals(false, s1Tr1.isDirty());
+ }
}
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java
index 9f9d4ec6cb..d30b39fa6a 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java
@@ -506,16 +506,18 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
applyLocalIDMapping(changeSetData, result);
}
+ CDOChangeSetData resultData = result.getChangeSetData();
+
// New objects
- applyNewObjects(changeSetData.getNewObjects(), result.getChangeSetData().getNewObjects());
+ applyNewObjects(changeSetData.getNewObjects(), resultData.getNewObjects());
// Detached objects
- Set<CDOObject> detachedSet = applyDetachedObjects(changeSetData.getDetachedObjects(), result.getChangeSetData()
- .getDetachedObjects());
+ Set<CDOObject> detachedSet = applyDetachedObjects(changeSetData.getDetachedObjects(),
+ resultData.getDetachedObjects());
// Changed objects
Map<CDOID, InternalCDORevision> oldRevisions = applyChangedObjects(changeSetData.getChangedObjects(),
- ancestorProvider, targetProvider, keepVersions, result.getChangeSetData().getChangedObjects());
+ ancestorProvider, targetProvider, keepVersions, resultData.getChangedObjects());
// Delta notifications
Collection<CDORevisionDelta> notificationDeltas = lastSavepoint.getRevisionDeltas2().values();
@@ -617,6 +619,7 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
{
Map<CDOID, InternalCDORevision> oldRevisions = new HashMap<CDOID, InternalCDORevision>();
+ Map<CDOID, CDOObject> detachedObjects = lastSavepoint.getDetachedObjects();
Map<CDOID, CDOObject> dirtyObjects = lastSavepoint.getDirtyObjects();
Map<CDOID, CDORevisionDelta> revisionDeltas = lastSavepoint.getRevisionDeltas2();
@@ -664,9 +667,9 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
result.add(targetGoalDelta);
// handle reattached objects.
- if (lastSavepoint.getDetachedObjects().containsKey(id))
+ if (detachedObjects.containsKey(id))
{
- CDOStateMachine.INSTANCE.attach(object, this);
+ CDOStateMachine.INSTANCE.internalReattach(object, this);
}
object.cdoInternalSetState(CDOState.DIRTY);
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOStateMachine.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOStateMachine.java
index 5356840243..0d1cddedac 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOStateMachine.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOStateMachine.java
@@ -11,7 +11,6 @@
*/
package org.eclipse.emf.internal.cdo.view;
-import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.CDOState;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDTemp;
@@ -507,6 +506,57 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
process(object, CDOEvent.ATTACH, null);
}
+ public void internalReattach(InternalCDOObject object, InternalCDOTransaction transaction)
+ {
+ InternalCDORevisionManager revisionManager = transaction.getSession().getRevisionManager();
+ InternalCDORevision cleanRevision = transaction.getCleanRevisions().get(object).copy();
+ CDOID id = cleanRevision.getID();
+
+ // Bug 373096: Determine clean revision of the CURRENT/LAST savepoint
+ InternalCDOSavepoint savepoint = transaction.getFirstSavepoint();
+ while (savepoint.getNextSavepoint() != null)
+ {
+ CDORevisionDelta delta = savepoint.getRevisionDeltas2().get(id);
+ if (delta != null)
+ {
+ delta.apply(cleanRevision);
+ }
+
+ savepoint = savepoint.getNextSavepoint();
+ }
+
+ object.cdoInternalSetID(id);
+ object.cdoInternalSetView(transaction);
+
+ // Construct a new revision
+ CDORevisionFactory factory = revisionManager.getFactory();
+ InternalCDORevision revision = (InternalCDORevision)factory.createRevision(object.eClass());
+ revision.setID(id);
+ revision.setBranchPoint(cleanRevision.getBranch().getHead());
+ revision.setVersion(cleanRevision.getVersion());
+
+ // Populate the revision based on the values in the CDOObject
+ object.cdoInternalSetRevision(revision);
+ object.cdoInternalPostAttach();
+
+ // Compute a revision delta and register it with the tx
+ CDORevisionDelta revisionDelta = revision.compare(cleanRevision);
+ if (revisionDelta.isEmpty())
+ {
+ changeState(object, CDOState.CLEAN);
+ }
+ else
+ {
+ transaction.registerRevisionDelta(revisionDelta);
+ transaction.registerDirty(object, (CDOFeatureDelta)null);
+ changeState(object, CDOState.DIRTY);
+ }
+
+ // Add the object to the set of reattached objects
+ InternalCDOSavepoint lastSavepoint = transaction.getLastSavepoint();
+ lastSavepoint.getReattachedObjects().put(id, object);
+ }
+
/**
* Prepares a tree of transient objects to be subsequently {@link AttachTransition attached} to a CDOView.
* <p>
@@ -668,53 +718,7 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent
{
public void execute(InternalCDOObject object, CDOState state, CDOEvent event, InternalCDOTransaction transaction)
{
- InternalCDORevisionManager revisionManager = transaction.getSession().getRevisionManager();
- InternalCDORevision cleanRevision = transaction.getCleanRevisions().get(object).copy();
- CDOID id = cleanRevision.getID();
-
- // Bug 373096: Determine clean revision of the CURRENT/LAST savepoint
- InternalCDOSavepoint savepoint = transaction.getFirstSavepoint();
- while (savepoint.getNextSavepoint() != null)
- {
- CDORevisionDelta delta = savepoint.getRevisionDeltas2().get(id);
- if (delta != null)
- {
- delta.apply(cleanRevision);
- }
-
- savepoint = savepoint.getNextSavepoint();
- }
-
- object.cdoInternalSetID(id);
- object.cdoInternalSetView(transaction);
-
- // Construct a new revision
- CDORevisionFactory factory = revisionManager.getFactory();
- InternalCDORevision revision = (InternalCDORevision)factory.createRevision(object.eClass());
- revision.setID(id);
- revision.setBranchPoint(cleanRevision.getBranch().getHead());
- revision.setVersion(cleanRevision.getVersion());
-
- // Populate the revision based on the values in the CDOObject
- object.cdoInternalSetRevision(revision);
- object.cdoInternalPostAttach();
-
- // Compute a revision delta and register it with the tx
- CDORevisionDelta revisionDelta = revision.compare(cleanRevision);
- if (revisionDelta.isEmpty())
- {
- changeState(object, CDOState.CLEAN);
- }
- else
- {
- transaction.registerRevisionDelta(revisionDelta);
- transaction.registerDirty(object, (CDOFeatureDelta)null);
- changeState(object, CDOState.DIRTY);
- }
-
- // Add the object to the set of reattached objects
- Map<CDOID, CDOObject> reattachedObjects = transaction.getLastSavepoint().getReattachedObjects();
- reattachedObjects.put(id, object);
+ internalReattach(object, transaction);
// Bug 385268
InternalEObject reattachedObject = object.cdoInternalInstance();

Back to the top