summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCaspar De Groot2010-10-01 05:36:23 (EDT)
committerCaspar De Groot2010-10-01 05:36:23 (EDT)
commitcac0eacb88af83d7b3fc7ed4ae77510c01b6e372 (patch)
tree68381b69a4784f4fecd02f70e57fae90e1ddc454
parent4f1a1b7e87529058446bd90ea4d544faa8c9cda5 (diff)
downloadcdo-cac0eacb88af83d7b3fc7ed4ae77510c01b6e372.zip
cdo-cac0eacb88af83d7b3fc7ed4ae77510c01b6e372.tar.gz
cdo-cac0eacb88af83d7b3fc7ed4ae77510c01b6e372.tar.bz2
[290032] Sticky views
https://bugs.eclipse.org/bugs/show_bug.cgi?id=290032
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllConfigs.java1
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/StickyViewsTest.java423
-rw-r--r--plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_273233_Test.java27
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java9
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/transaction/CDOTransactionImpl.java57
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java24
-rw-r--r--plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOView.java5
7 files changed, 532 insertions, 14 deletions
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllConfigs.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllConfigs.java
index b0e9f3b..f4284a3 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllConfigs.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/AllConfigs.java
@@ -167,6 +167,7 @@ public abstract class AllConfigs extends ConfigTestSuite
testClasses.add(DynamicPackageTest.class);
testClasses.add(LegacyTest.class);
testClasses.add(XRefTest.class);
+ testClasses.add(StickyViewsTest.class);
// Specific for MEMStore
testClasses.add(MEMStoreQueryTest.class);
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/StickyViewsTest.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/StickyViewsTest.java
new file mode 100644
index 0000000..5171217
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/StickyViewsTest.java
@@ -0,0 +1,423 @@
+/**
+ * Copyright (c) 2004 - 2010 Eike Stepper (Berlin, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Caspar De Groot - initial API and implementation
+ */
+package org.eclipse.emf.cdo.tests;
+
+import org.eclipse.emf.cdo.CDOObject;
+import org.eclipse.emf.cdo.common.id.CDOID;
+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.spi.common.revision.InternalCDORevisionManager;
+import org.eclipse.emf.cdo.tests.config.IRepositoryConfig;
+import org.eclipse.emf.cdo.tests.config.impl.ModelConfig;
+import org.eclipse.emf.cdo.tests.model1.Category;
+import org.eclipse.emf.cdo.tests.model1.Company;
+import org.eclipse.emf.cdo.transaction.CDOTransaction;
+import org.eclipse.emf.cdo.util.CDOUtil;
+import org.eclipse.emf.cdo.util.CommitException;
+import org.eclipse.emf.cdo.util.ObjectNotFoundException;
+
+import org.eclipse.emf.common.util.EList;
+
+/**
+ * @author Caspar De Groot
+ */
+public class StickyViewsTest extends AbstractCDOTest
+{
+ private static final int N_CATEGORIES = 3;
+
+ private void checkSkip()
+ {
+ // Sticky behavior is only enabled when store supports auditing, so these tests are
+ // meaningless and/or guaranteed to fail if this is not the case
+ skipUnlessAuditing();
+ }
+
+ public void test_removeLast() throws CommitException
+ {
+ test(new AbstractClosure()
+ {
+ public void doChange(EList<Category> categories)
+ {
+ categories.remove(N_CATEGORIES - 1);
+ }
+ });
+ }
+
+ public void test_removeFirst() throws CommitException
+ {
+ test(new AbstractClosure()
+ {
+ public void doChange(EList<Category> categories)
+ {
+ categories.remove(0);
+ }
+ });
+ }
+
+ public void test_changeName() throws CommitException
+ {
+ test(new AbstractClosure()
+ {
+ public void doChange(EList<Category> categories)
+ {
+ categories.get(0).setName("zzz");
+ }
+
+ @Override
+ public void verify(EList<Category> categories)
+ {
+ assertEquals("category0", categories.get(0).getName());
+ }
+ });
+ }
+
+ private void test(Closure closure) throws CommitException
+ {
+ checkSkip();
+
+ // Create a company with N categories
+ Company company1 = getModel1Factory().createCompany();
+ company1.setName("company");
+ for (int i = 0; i < N_CATEGORIES; i++)
+ {
+ Category category = getModel1Factory().createCategory();
+ company1.getCategories().add(category);
+ category.setName("category" + i);
+ }
+
+ // Persist it
+ CDOSession session = openSession();
+ CDOTransaction transaction1 = session.openTransaction();
+ CDOResource res = transaction1.createResource("/res1");
+ res.getContents().add(company1);
+ transaction1.commit();
+
+ assertEquals(N_CATEGORIES, company1.getCategories().size());
+
+ // Fetch the same company in another session/tx
+ CDOSession session2 = openSession();
+ session2.options().setPassiveUpdateEnabled(false);
+ CDOTransaction transaction2 = session2.openTransaction();
+ CDOResource res2 = transaction2.getResource("/res1");
+ Company company2 = (Company)res2.getContents().get(0);
+
+ // In the 1st session, manipulate the categories
+ closure.doChange(company1.getCategories());
+ transaction1.commit();
+
+ // Clear server-side cache to force loading of revisions from IStore
+ IRepository repo = getRepositoryConfig().getRepository(IRepositoryConfig.REPOSITORY_NAME);
+ ((InternalCDORevisionManager)repo.getRevisionManager()).getCache().clear();
+
+ // Verify that in 2nd session, all categories still appear to be present
+ closure.verify(company2.getCategories());
+
+ msg("Done");
+
+ transaction1.close();
+ session.close();
+
+ session2.close();
+ transaction2.close();
+ }
+
+ /**
+ * Ensures that a newly committed object in this tx, can be reloaded from the server.
+ */
+ public void test_newCommittedObject() throws CommitException
+ {
+ checkSkip();
+
+ CDOSession session = openSession();
+ session.options().setPassiveUpdateEnabled(false);
+
+ CDOTransaction transaction1 = session.openTransaction();
+ CDOResource res = transaction1.createResource("/res1");
+ Company company1 = getModel1Factory().createCompany();
+ res.getContents().add(company1);
+ transaction1.commit();
+
+ // Make dirty, then roll back, so as to force PROXY state
+ //
+ company1.setName("company1");
+ transaction1.rollback();
+
+ // Clear cache to force loading of revisions from server
+ //
+ ((InternalCDORevisionManager)session.getRevisionManager()).getCache().clear();
+
+ // Clear server-side cache to force loading of revisions from IStore
+ //
+ IRepository repo = getRepositoryConfig().getRepository(IRepositoryConfig.REPOSITORY_NAME);
+ ((InternalCDORevisionManager)repo.getRevisionManager()).getCache().clear();
+
+ // Check if the object really transitioned to PROXY
+ // (Can't do this for legacy objects, as the CDOAdapter will reload the revision during
+ // postRollback, see CDOLegacyWrapper#cdoInternalPostRollback.)
+ if (!getScenario().getModelConfig().getName().equals(ModelConfig.Legacy.NAME))
+ {
+ assertProxy(company1);
+ }
+
+ msg(company1.getName());
+
+ CDOID id = CDOUtil.getCDOObject(company1).cdoID();
+ company1 = null;
+
+ CDOObject obj = transaction1.getObject(id);
+ assertNotNull(obj);
+
+ session.close();
+ }
+
+ /**
+ * Ensures that an object that was updated and committed in this tx, can be reloaded in its *updated* state from the
+ * server.
+ */
+ public void test_dirtyCommittedObject() throws CommitException
+ {
+ checkSkip();
+
+ // Put a company in the repo
+ {
+ CDOSession sess = openSession();
+ CDOTransaction tx = sess.openTransaction();
+ CDOResource res = tx.createResource("/res1");
+ Company company1 = getModel1Factory().createCompany();
+ company1.setName("aaa");
+ res.getContents().add(company1);
+ tx.commit();
+ sess.close();
+ }
+
+ // Load it up in a different, sticky session
+ {
+ CDOSession sess = openSession();
+ CDOTransaction tx = sess.openTransaction();
+ sess.options().setPassiveUpdateEnabled(false);
+ CDOResource res = tx.getResource("/res1");
+
+ // Save with a new name
+ Company company1 = (Company)res.getContents().get(0);
+ company1.setName("bbb");
+ tx.commit();
+
+ // Make dirty then roll back, so as to force PROXY state
+ company1.setName("ccc");
+ tx.rollback();
+
+ // Check if the object really transitioned to PROXY
+ // (Can't do this for legacy objects, as the CDOAdapter will reload the revision during
+ // postRollback, see CDOLegacyWrapper#cdoInternalPostRollback.)
+ if (!getScenario().getModelConfig().getName().equals(ModelConfig.Legacy.NAME))
+ {
+ assertProxy(company1);
+ }
+
+ // Clear cache to force loading of revisions from server
+ //
+ ((InternalCDORevisionManager)sess.getRevisionManager()).getCache().clear();
+
+ // Clear server-side cache to force loading of revisions from IStore
+ //
+ IRepository repo = getRepositoryConfig().getRepository(IRepositoryConfig.REPOSITORY_NAME);
+ ((InternalCDORevisionManager)repo.getRevisionManager()).getCache().clear();
+
+ String name = company1.getName();
+ assertEquals("bbb", name);
+ sess.close();
+ }
+ }
+
+ /**
+ * Ensures that an object that was removed in this tx, can no longer be loaded (even though the sticky time is still
+ * set to a time when the object still existed!)
+ */
+ public void test_detachedCommittedObject() throws CommitException
+ {
+ checkSkip();
+
+ // Put a company in the repo
+ {
+ CDOSession sess = openSession();
+ CDOTransaction tx = sess.openTransaction();
+ CDOResource res = tx.createResource("/res1");
+ Company company1 = getModel1Factory().createCompany();
+ company1.setName("aaa");
+ res.getContents().add(company1);
+ tx.commit();
+ sess.close();
+ }
+
+ // Load it up in a different, sticky session
+ {
+ CDOSession sess = openSession();
+ CDOTransaction tx = sess.openTransaction();
+ sess.options().setPassiveUpdateEnabled(false);
+ CDOResource res = tx.getResource("/res1");
+
+ // Remove it
+ Company company1 = (Company)res.getContents().get(0);
+ CDOID companyID = CDOUtil.getCDOObject(company1).cdoID();
+ res.getContents().remove(company1);
+ tx.commit();
+
+ // Clear cache to force loading of revisions from server
+ //
+ ((InternalCDORevisionManager)sess.getRevisionManager()).getCache().clear();
+
+ // Clear server-side cache to force loading of revisions from IStore
+ //
+ IRepository repo = getRepositoryConfig().getRepository(IRepositoryConfig.REPOSITORY_NAME);
+ ((InternalCDORevisionManager)repo.getRevisionManager()).getCache().clear();
+
+ try
+ {
+ tx.getObject(companyID);
+ fail("Should have thrown " + ObjectNotFoundException.class.getSimpleName());
+ }
+ catch (ObjectNotFoundException e)
+ {
+ // Good
+ }
+
+ sess.close();
+ }
+ }
+
+ public void test_refresh() throws CommitException
+ {
+ checkSkip();
+
+ CDOSession sess = openSession();
+ CDOTransaction tx = sess.openTransaction();
+ sess.options().setPassiveUpdateEnabled(false);
+
+ CDOResource res = tx.createResource("/res1");
+ Company company1 = getModel1Factory().createCompany();
+ company1.setName("aaa");
+ res.getContents().add(company1);
+ tx.commit(); // Puts the company in committedSinceLastRefresh
+
+ sess.refresh(); // Removes the company from committedSinceLastRefresh
+
+ // Make dirty then rollback to force proxy
+ company1.setName("bbb");
+ tx.rollback();
+
+ // Clear cache to force loading of revisions from server
+ //
+ ((InternalCDORevisionManager)sess.getRevisionManager()).getCache().clear();
+
+ doOtherSession(); // Creates a new revision on the server
+
+ // Check if the object really transitioned to PROXY
+ // (Can't do this for legacy objects, as the CDOAdapter will reload the revision during
+ // postRollback, see CDOLegacyWrapper#cdoInternalPostRollback.)
+ if (!getScenario().getModelConfig().getName().equals(ModelConfig.Legacy.NAME))
+ {
+ assertProxy(company1);
+ }
+
+ assertEquals("The company name should not have the value set in the other session", "aaa", company1.getName());
+
+ sess.close();
+ }
+
+ public void test_otherSessionCommittedLatest() throws CommitException
+ {
+ checkSkip();
+
+ CDOSession sess = openSession();
+ CDOTransaction tx = sess.openTransaction();
+ sess.options().setPassiveUpdateEnabled(false);
+
+ CDOResource res = tx.createResource("/res1");
+ Company company1 = getModel1Factory().createCompany();
+ company1.setName("aaa");
+ res.getContents().add(company1);
+ tx.commit(); // Puts the company in committedSinceLastRefresh
+
+ // Make dirty then rollback to force proxy
+ company1.setName("bbb");
+ tx.rollback();
+
+ // Clear cache to force loading of revisions from server
+ ((InternalCDORevisionManager)sess.getRevisionManager()).getCache().clear();
+
+ doOtherSession(); // Creates a new revision on the server
+
+ // Check if the object really transitioned to PROXY
+ // (Can't do this for legacy objects, as the CDOAdapter will reload the revision during
+ // postRollback, see CDOLegacyWrapper#cdoInternalPostRollback.)
+ if (!getScenario().getModelConfig().getName().equals(ModelConfig.Legacy.NAME))
+ {
+ assertProxy(company1);
+ }
+
+ // Verify that this session still fetches the revision that *this* session just committed,
+ // rather than the latest revision, which was committed by the other session
+ assertEquals("aaa", company1.getName());
+
+ sess.close();
+ }
+
+ private void doOtherSession() throws CommitException
+ {
+ CDOSession sess = openSession();
+ CDOTransaction tx = sess.openTransaction();
+ CDOResource res = tx.getResource("/res1");
+ Company company1 = (Company)res.getContents().get(0);
+ company1.setName("ccc");
+ tx.commit();
+ tx.close();
+ sess.close();
+ }
+
+ /**
+ * @author Caspar De Groot
+ */
+ private interface Closure
+ {
+ public void doChange(EList<Category> categories);
+
+ public void verify(EList<Category> categories);
+ }
+
+ /**
+ * @author Caspar De Groot
+ */
+ private abstract class AbstractClosure implements Closure
+ {
+ public void verify(EList<Category> categories)
+ {
+ assertEquals(N_CATEGORIES, categories.size());
+
+ // Now fetch each category in the 2nd session
+ for (int i = 0; i < N_CATEGORIES; i++)
+ {
+ msg("Getting index " + i);
+ assertEquals(N_CATEGORIES, categories.size());
+
+ try
+ {
+ Category cat = categories.get(i);
+ assertNotNull(cat);
+ }
+ catch (ObjectNotFoundException e)
+ {
+ fail("Should not have thrown " + ObjectNotFoundException.class.getName());
+ }
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_273233_Test.java b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_273233_Test.java
index 9f83ea5..2202597 100644
--- a/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_273233_Test.java
+++ b/plugins/org.eclipse.emf.cdo.tests/src/org/eclipse/emf/cdo/tests/bugzilla/Bugzilla_273233_Test.java
@@ -45,26 +45,32 @@ public class Bugzilla_273233_Test extends AbstractCDOTest
CDOSession session = openSession();
session.options().setPassiveUpdateEnabled(false);
- CDOSession session2 = openSession();
-
CDOTransaction trans = session.openTransaction();
- CDOTransaction trans2 = session2.openTransaction();
CDOResource res = trans.createResource("/test/1");
trans.commit();
- session2.options().setPassiveUpdateEnabled(false);
+ CDOSession session2 = openSession();
+ session2.options().setPassiveUpdateEnabled(false);
+ CDOTransaction trans2 = session2.openTransaction();
CDOResource res2 = trans2.getResource("/test/1");
+
+ // Add company in sess/tx #1
Company company = getModel1Factory().createCompany();
res.getContents().add(company);
+
+ // Add company in sess/tx #2
Company company2 = getModel1Factory().createCompany();
res2.getContents().add(company2);
+ // Commit tx #1
trans.commit();
assertFalse(FSMUtil.isConflict(res2));
+
session2.refresh();
assertTrue(FSMUtil.isConflict(res2));
+
try
{
trans2.commit();
@@ -84,22 +90,27 @@ public class Bugzilla_273233_Test extends AbstractCDOTest
CDOSession session = openSession();
session.options().setPassiveUpdateEnabled(false);
- CDOSession session2 = openSession();
-
CDOTransaction trans = session.openTransaction();
- CDOTransaction trans2 = session2.openTransaction();
CDOResource res = trans.createResource("/test/1");
trans.commit();
- session2.options().setPassiveUpdateEnabled(false);
+ CDOSession session2 = openSession();
+ session2.options().setPassiveUpdateEnabled(false);
+ CDOTransaction trans2 = session2.openTransaction();
CDOResource res2 = trans2.getResource("/test/1");
+
+ // Add company in sess/tx #1
Company company = getModel1Factory().createCompany();
res.getContents().add(company);
+
+ // Add company in sess/tx #2
Company company2 = getModel1Factory().createCompany();
res2.getContents().add(company2);
+ // Commit tx #1
trans.commit();
+
clearCache(session2.getRevisionManager());
assertFalse(FSMUtil.isConflict(res2));
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java
index 56ebe8f..e0d9dc5 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java
@@ -531,6 +531,7 @@ public abstract class CDOSessionImpl extends Container<CDOView> implements Inter
RefreshSessionResult result = sessionProtocol.refresh(lastUpdateTime, viewedRevisions, initialChunkSize,
enablePassiveUpdates);
+ setLastUpdateTime(result.getLastUpdateTime());
registerPackageUnits(result.getPackageUnits());
@@ -538,11 +539,9 @@ public abstract class CDOSessionImpl extends Container<CDOView> implements Inter
{
CDOBranch branch = entry.getKey();
List<InternalCDOView> branchViews = entry.getValue();
-
processRefreshSessionResult(result, branch, branchViews, viewedRevisions);
}
- setLastUpdateTime(result.getLastUpdateTime());
return result.getLastUpdateTime();
}
}
@@ -893,7 +892,11 @@ public abstract class CDOSessionImpl extends Container<CDOView> implements Inter
}
fireInvalidationEvent(sender, commitInfo);
- setLastUpdateTime(commitInfo.getTimeStamp());
+
+ if (options.isPassiveUpdateEnabled())
+ {
+ setLastUpdateTime(commitInfo.getTimeStamp());
+ }
}
public Object getInvalidationLock()
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 d1d8331..adb0057 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
@@ -11,6 +11,7 @@
* Victor Roldan Betancort - maintenance
* Gonzague Reydet - bug 298334
* Andre Dietisheim - bug 256649
+ * Caspar De Groot - bug 290032 (Sticky views)
*/
package org.eclipse.emf.internal.cdo.transaction;
@@ -193,8 +194,20 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
}
};
+ /**
+ * An optional set to specify which objects in this TX are to be committed by {@link #commit()}
+ */
private Set<EObject> committables;
+ /**
+ * A map to track for every object that was committed since this TX's last refresh, onto what CDOBranchPoint it was
+ * committed. (Used only for sticky transactions, see bug 290032 - Sticky views.)
+ */
+ private Map<CDOID, CDOBranchPoint> committedSinceLastRefresh = new HashMap<CDOID, CDOBranchPoint>();
+
+ /**
+ * A map to hold a clean (i.e. unmodified) revision for objects that have been modified or detached.
+ */
private Map<InternalCDOObject, InternalCDORevision> cleanRevisions = new HashMap<InternalCDOObject, InternalCDORevision>();
public CDOTransactionImpl(CDOBranch branch)
@@ -1899,6 +1912,23 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
super.doDeactivate();
}
+ @Override
+ protected CDOBranchPoint getBranchPointForID(CDOID id)
+ {
+ if (isSticky())
+ {
+ CDOBranchPoint branchPoint = committedSinceLastRefresh.get(id);
+ if (branchPoint == null)
+ {
+ branchPoint = getBranch().getPoint(getSession().getLastUpdateTime());
+ }
+
+ return branchPoint;
+ }
+
+ return this;
+ }
+
/**
* Bug 298561: This override removes references to remotely detached objects that are present in any DIRTY or NEW
* objects.
@@ -1925,6 +1955,12 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
removeCrossReferences(cachedNewObjects, referencedOIDs);
}
+ // Bug 290032 - Sticky views
+ if (isSticky())
+ {
+ committedSinceLastRefresh.clear();
+ }
+
return super.invalidate(lastUpdateTime, allChangedObjects, allDetachedObjects, deltas, revisionDeltas,
detachedObjects);
}
@@ -2222,6 +2258,27 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa
InternalCDOSession session = getSession();
session.invalidate(commitInfo, transaction);
+ // Bug 290032 - Sticky views
+ if (isSticky())
+ {
+ CDOBranchPoint commitBranchPoint = CDOBranchUtil.copyBranchPoint(result);
+ for (CDOObject object : getNewObjects().values()) // Note: keyset() does not work because ID mappings are
+ // not applied there!
+ {
+ committedSinceLastRefresh.put(object.cdoID(), commitBranchPoint);
+ }
+
+ for (CDOID id : getDirtyObjects().keySet())
+ {
+ committedSinceLastRefresh.put(id, commitBranchPoint);
+ }
+
+ for (CDOID id : getDetachedObjects().keySet())
+ {
+ committedSinceLastRefresh.put(id, commitBranchPoint);
+ }
+ }
+
CDOTransactionHandler[] handlers = getTransactionHandlers();
if (handlers != null)
{
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java
index b5adab0..2876038 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOViewImpl.java
@@ -42,6 +42,7 @@ import org.eclipse.emf.cdo.spi.common.branch.CDOBranchUtil;
import org.eclipse.emf.cdo.spi.common.model.InternalCDOPackageRegistry;
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.InternalCDORevisionManager;
import org.eclipse.emf.cdo.transaction.CDOCommitContext;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.util.CDOURIUtil;
@@ -933,10 +934,27 @@ public class CDOViewImpl extends Lifecycle implements InternalCDOView
public InternalCDORevision getRevision(CDOID id, boolean loadOnDemand)
{
- CDORevisionManager revisionManager = session.getRevisionManager();
+ InternalCDORevisionManager revisionManager = session.getRevisionManager();
int initialChunkSize = session.options().getCollectionLoadingPolicy().getInitialChunkSize();
- return (InternalCDORevision)revisionManager.getRevision(id, this, initialChunkSize, CDORevision.DEPTH_NONE,
- loadOnDemand);
+ CDOBranchPoint branchPoint = getBranchPointForID(id);
+ return revisionManager.getRevision(id, branchPoint, initialChunkSize, CDORevision.DEPTH_NONE, loadOnDemand);
+ }
+
+ protected CDOBranchPoint getBranchPointForID(CDOID id)
+ {
+ if (isSticky())
+ {
+ return getBranch().getPoint(session.getLastUpdateTime());
+ }
+
+ return this;
+ }
+
+ public boolean isSticky()
+ {
+ boolean passiveUpdate = session.options().isPassiveUpdateEnabled();
+ boolean supportingAudits = session.getRepositoryInfo().isSupportingAudits();
+ return !passiveUpdate && supportingAudits;
}
public void prefetchRevisions(CDOID id, int depth)
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOView.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOView.java
index cc39150..6ef5345 100644
--- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOView.java
+++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/spi/cdo/InternalCDOView.java
@@ -55,6 +55,11 @@ public interface InternalCDOView extends CDOView, CDOIDProvider, ILifecycle
public CDOStore getStore();
+ /**
+ * @since 4.0
+ */
+ public boolean isSticky();
+
public InternalCDOTransaction toTransaction();
public void attachResource(CDOResourceImpl resource);