Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Stepper2009-11-07 04:41:52 -0500
committerEike Stepper2009-11-07 04:41:52 -0500
commit8f8228673b8b6c1007ef3644c8416272cedbf5ab (patch)
treeb815c896ec1d194a824c7abb99eb58d80fd015a1 /plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction
parentb9d57f215e8203f11d09991a20bcbcdfa7127ad4 (diff)
downloadcdo-8f8228673b8b6c1007ef3644c8416272cedbf5ab.tar.gz
cdo-8f8228673b8b6c1007ef3644c8416272cedbf5ab.tar.xz
cdo-8f8228673b8b6c1007ef3644c8416272cedbf5ab.zip
[294528] Preserve CDOID for re-attached CDOObjects
https://bugs.eclipse.org/bugs/show_bug.cgi?id=294528
Diffstat (limited to 'plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction')
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOSavepointImpl.java31
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java54
2 files changed, 81 insertions, 4 deletions
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOSavepointImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOSavepointImpl.java
index 3460edf310..e6535985e6 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOSavepointImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOSavepointImpl.java
@@ -66,6 +66,8 @@ public class CDOSavepointImpl extends AbstractSavepoint
}
};
+ private Map<CDOID, CDOObject> reattachedObjects = new HashMap<CDOID, CDOObject>();
+
private ConcurrentMap<CDOID, CDORevisionDelta> revisionDeltas = new ConcurrentHashMap<CDOID, CDORevisionDelta>();
/**
@@ -80,7 +82,7 @@ public class CDOSavepointImpl extends AbstractSavepoint
{
super(transaction, lastSavepoint);
isDirty = transaction.isDirty();
- if (getPreviousSavepoint() == null)
+ if (lastSavepoint == null)
{
sharedDetachedObjects = new HashSet<CDOID>();
}
@@ -295,17 +297,34 @@ public class CDOSavepointImpl extends AbstractSavepoint
{
if (getPreviousSavepoint() == null)
{
- return Collections.unmodifiableMap(getDetachedObjects());
+ Map<CDOID, CDOObject> detachedObjects = getDetachedObjects();
+
+ // Bug 283985 (Re-attachment):
+ // Object is only included if it was not reattached in a later savepoint
+ for (CDOID id : getReattachedObjects().keySet())
+ {
+ detachedObjects.remove(id);
+ }
+
+ return Collections.unmodifiableMap(detachedObjects);
}
Map<CDOID, CDOObject> detachedObjects = new HashMap<CDOID, CDOObject>();
+ Set<CDOID> reattachedObjectIDs = new HashSet<CDOID>(); // Bug 283985 (Re-attachment)
for (CDOSavepointImpl savepoint = this; savepoint != null; savepoint = savepoint.getPreviousSavepoint())
{
+ reattachedObjectIDs.addAll(savepoint.getReattachedObjects().keySet());
+
for (Entry<CDOID, CDOObject> entry : savepoint.getDetachedObjects().entrySet())
{
if (!entry.getKey().isTemporary())
{
- detachedObjects.put(entry.getKey(), entry.getValue());
+ // Bug 283985 (Re-attachment):
+ // Object is only included if it was not reattached in a later savepoint
+ if (!reattachedObjectIDs.contains(entry.getKey()))
+ {
+ detachedObjects.put(entry.getKey(), entry.getValue());
+ }
}
}
}
@@ -313,6 +332,12 @@ public class CDOSavepointImpl extends AbstractSavepoint
return detachedObjects;
}
+ // Bug 283985 (Re-attachment)
+ public Map<CDOID, CDOObject> getReattachedObjects()
+ {
+ return reattachedObjects;
+ }
+
public void recalculateSharedDetachedObjects()
{
sharedDetachedObjects.clear();
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 ecdf2c7616..81d5ca2a3b 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
@@ -34,6 +34,7 @@ import org.eclipse.emf.cdo.eresource.EresourceFactory;
import org.eclipse.emf.cdo.eresource.impl.CDOResourceImpl;
import org.eclipse.emf.cdo.eresource.impl.CDOResourceNodeImpl;
import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageUnit;
+import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta;
import org.eclipse.emf.cdo.transaction.CDOConflictResolver;
import org.eclipse.emf.cdo.transaction.CDOSavepoint;
@@ -83,6 +84,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.WeakHashMap;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;
@@ -117,6 +119,9 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
private CDOTransactionStrategy transactionStrategy;
+ // Bug 283985 (Re-attachment)
+ private WeakHashMap<InternalCDOObject, InternalCDORevision> formerRevisions = new WeakHashMap<InternalCDOObject, InternalCDORevision>();
+
/**
* @since 2.0
*/
@@ -733,6 +738,10 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
removeObjects(itrSavepoint.getNewResources().values());
removeObjects(itrSavepoint.getNewObjects().values());
+ // Bug 283985 (Re-attachment): Objects that were reattached must also be removed
+ Collection<CDOObject> reattachedObjects = itrSavepoint.getReattachedObjects().values();
+ removeObjects(reattachedObjects);
+
Map<CDOID, CDORevisionDelta> revisionDeltas = itrSavepoint.getRevisionDeltas();
if (!revisionDeltas.isEmpty())
{
@@ -769,7 +778,13 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
if (!entryDirtyObject.getKey().isTemporary())
{
InternalCDOObject internalDirtyObject = (InternalCDOObject)entryDirtyObject.getValue();
- CDOStateMachine.INSTANCE.rollback(internalDirtyObject);
+
+ // Bug 283985 (Re-attachment): Skip objects that were reattached, because
+ // they were already reset to TRANSIENT earlier in this method
+ if (!reattachedObjects.contains(internalDirtyObject))
+ {
+ CDOStateMachine.INSTANCE.rollback(internalDirtyObject);
+ }
}
}
@@ -907,6 +922,15 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
else
{
getLastSavepoint().getDetachedObjects().put(object.cdoID(), object);
+
+ if (!formerRevisions.containsKey(object))
+ {
+ formerRevisions.put(object, object.cdoRevision());
+ }
+
+ // Object may have been reattached previously, in which case it must
+ // here be removed from the collection of reattached objects
+ lastSavepoint.getReattachedObjects().remove(object.cdoID());
}
if (!dirty)
@@ -1305,6 +1329,34 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
return lastSavepoint.getAllDetachedObjects();
}
+ public Map<InternalCDOObject, InternalCDORevision> getFormerRevisions()
+ {
+ return formerRevisions;
+ }
+
+ @Override
+ protected CDOID getID(InternalCDOObject object, boolean onlyPersistedID)
+ {
+ // Bug 283985 (Re-attachment): We consult the formerRevision map before delegating
+ // to the super implementation. Note that we *abuse* the onlyPersistedID
+ // argument to determine if we should disregard the formerRevision map. We need
+ // to disregard it when this gets called during commit, and it just so happens
+ // that only during commit it is being called with onlyPersistedID = false. So
+ // this code exploits a regularity in the calling code, rather than interpreting
+ // the onlyPersistedID argument in accordance with its intended meaning. Indeed
+ // this is a very fragile hack...
+ if (onlyPersistedID)
+ {
+ CDORevision formerRevision = formerRevisions.get(object);
+ if (formerRevision != null)
+ {
+ return formerRevision.getID();
+ }
+ }
+
+ return super.getID(object, onlyPersistedID);
+ }
+
/**
* @since 2.0
*/

Back to the top