Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Taal2012-11-24 08:36:11 -0500
committerMartin Taal2012-11-24 08:36:11 -0500
commitb90d0af5da43dfd67bd50393c4064a1313459c83 (patch)
tree0d94cfb6dd2b5aa580dacb75509af7ff8835a350 /plugins
parent1c86acebf8d4a65cc0da2cff41f6467dd22b7a7f (diff)
downloadcdo-b90d0af5da43dfd67bd50393c4064a1313459c83.tar.gz
cdo-b90d0af5da43dfd67bd50393c4064a1313459c83.tar.xz
cdo-b90d0af5da43dfd67bd50393c4064a1313459c83.zip
Combine hibernate and CDO versioning, use optimistic locking in hibernate
Diffstat (limited to 'plugins')
-rw-r--r--plugins/org.eclipse.emf.cdo.server.hibernate.teneo/src/org/eclipse/emf/cdo/server/hibernate/teneo/CDOEntityMapper.java2
-rw-r--r--plugins/org.eclipse.emf.cdo.server.hibernate/mappings/resource.hbm.xml4
-rw-r--r--plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/CDOAuditHandler.java21
-rw-r--r--plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateAuditHandler.java75
-rw-r--r--plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateStoreAccessor.java69
-rw-r--r--plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDORevisionTuplizer.java11
-rw-r--r--plugins/org.eclipse.emf.cdo.tests.hibernate/src/org/eclipse/emf/cdo/tests/hibernate/AllTestsHibernate.java20
-rw-r--r--plugins/org.eclipse.emf.cdo.tests.hibernate/src/org/eclipse/emf/cdo/tests/hibernate/CDOObjectHistoryTest.java351
8 files changed, 517 insertions, 36 deletions
diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate.teneo/src/org/eclipse/emf/cdo/server/hibernate/teneo/CDOEntityMapper.java b/plugins/org.eclipse.emf.cdo.server.hibernate.teneo/src/org/eclipse/emf/cdo/server/hibernate/teneo/CDOEntityMapper.java
index a44be5b6ba..0b86786304 100644
--- a/plugins/org.eclipse.emf.cdo.server.hibernate.teneo/src/org/eclipse/emf/cdo/server/hibernate/teneo/CDOEntityMapper.java
+++ b/plugins/org.eclipse.emf.cdo.server.hibernate.teneo/src/org/eclipse/emf/cdo/server/hibernate/teneo/CDOEntityMapper.java
@@ -74,7 +74,7 @@ public class CDOEntityMapper extends EntityMapper
final Element columnElement = containerElement.addElement("column").addAttribute("name", //$NON-NLS-1$ //$NON-NLS-2$
CDOHibernateConstants.CONTAINER_PROPERTY_COLUMN);
- final Element versionElement = entityElement.addElement("property"); //$NON-NLS-1$
+ final Element versionElement = entityElement.addElement("version"); //$NON-NLS-1$
// add cdo_teneo prefix to prop name prevent name clashes with
// efeatures which are accidentally called version
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=378050
diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/mappings/resource.hbm.xml b/plugins/org.eclipse.emf.cdo.server.hibernate/mappings/resource.hbm.xml
index 87748e0c18..d92d57c1ed 100644
--- a/plugins/org.eclipse.emf.cdo.server.hibernate/mappings/resource.hbm.xml
+++ b/plugins/org.eclipse.emf.cdo.server.hibernate/mappings/resource.hbm.xml
@@ -24,9 +24,9 @@
<generator class="native"/>
</id>
<discriminator column="`dtype`" type="string"/>
- <property name="e_version" column="`e_version`" type="java.lang.Integer" access="org.eclipse.emf.cdo.server.internal.hibernate.tuplizer.CDOSyntheticVersionPropertyHandler">
+ <version name="e_version" column="`e_version`" type="java.lang.Integer" >
<meta attribute="version">true</meta>
- </property>
+ </version>
<property name="resourceID" type="org.eclipse.emf.cdo.server.internal.hibernate.tuplizer.CDOIDUserType">
<column name="`resource_id`"/>
</property>
diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/CDOAuditHandler.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/CDOAuditHandler.java
index c61c639de6..7a74641c6b 100644
--- a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/CDOAuditHandler.java
+++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/CDOAuditHandler.java
@@ -12,6 +12,7 @@
package org.eclipse.emf.cdo.server.internal.hibernate;
import org.eclipse.emf.cdo.common.id.CDOID;
+import org.eclipse.emf.cdo.common.model.CDOClassifierRef;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.revision.CDORevisionData;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
@@ -67,6 +68,26 @@ public class CDOAuditHandler extends AuditHandler
return auditEClass != null;
}
+ public boolean isAudited(CDOID id)
+ {
+ if (!getDataStore().isAuditing())
+ {
+ return false;
+ }
+ if (!(id instanceof CDOClassifierRef.Provider))
+ {
+ return false;
+ }
+ CDOClassifierRef cdoClassifierRef = ((CDOClassifierRef.Provider)id).getClassifierRef();
+ final EClass eClass = HibernateUtil.getInstance().getEClass(cdoClassifierRef);
+ if (eClass == null)
+ {
+ return false;
+ }
+ final EClass auditEClass = getAuditingModelElement(eClass);
+ return auditEClass != null;
+ }
+
@Override
public EClass getEClass(Object o)
{
diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateAuditHandler.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateAuditHandler.java
index ea29dedb5f..93439fa1d1 100644
--- a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateAuditHandler.java
+++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateAuditHandler.java
@@ -11,6 +11,7 @@
*/
package org.eclipse.emf.cdo.server.internal.hibernate;
+import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.model.CDOClassifierRef;
@@ -18,6 +19,7 @@ import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.revision.CDORevisionHandler;
import org.eclipse.emf.cdo.eresource.EresourcePackage;
import org.eclipse.emf.cdo.spi.common.id.AbstractCDOIDLong;
+import org.eclipse.emf.cdo.spi.common.revision.DetachedCDORevision;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision;
import org.eclipse.emf.common.util.Enumerator;
@@ -34,7 +36,6 @@ import org.eclipse.emf.teneo.hibernate.auditing.model.teneoauditing.TeneoAuditKi
import org.hibernate.Query;
import org.hibernate.Session;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -50,9 +51,23 @@ public class HibernateAuditHandler
private HbDataStore cdoDataStore;
- public AuditHandler getAuditHandler()
+ public CDOAuditHandler getCDOAuditHandler()
{
- return cdoDataStore.getAuditHandler();
+ return (CDOAuditHandler)cdoDataStore.getAuditHandler();
+ }
+
+ public InternalCDORevision readRevisionByVersion(Session session, CDOID id, int version)
+ {
+ final CDOClassifierRef classifierRef = CDOIDUtil.getClassifierRef(id);
+ if (classifierRef == null)
+ {
+ throw new IllegalArgumentException("This CDOID type of " + id + " is not supported by this store."); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ final EClass eClass = HibernateUtil.getInstance().getEClass(classifierRef);
+ AuditVersionProvider auditVersionProvider = cdoDataStore.getAuditVersionProvider();
+ auditVersionProvider.setSession(session);
+ final TeneoAuditEntry auditEntry = auditVersionProvider.getAuditEntryForVersion(eClass, id, version);
+ return (InternalCDORevision)getCDORevision(session, auditEntry);
}
public InternalCDORevision readRevision(Session session, CDOID id, long timeStamp)
@@ -72,10 +87,6 @@ public class HibernateAuditHandler
AuditVersionProvider auditVersionProvider = cdoDataStore.getAuditVersionProvider();
auditVersionProvider.setSession(session);
final TeneoAuditEntry auditEntry = auditVersionProvider.getAuditEntry(eClass, id, timeStamp);
- if (auditEntry.getTeneo_audit_kind() == TeneoAuditKind.DELETE)
- {
- return null;
- }
return getCDORevision(session, auditEntry);
}
@@ -87,17 +98,37 @@ public class HibernateAuditHandler
protected CDORevision convertAuditEntryToCDORevision(TeneoAuditEntry teneoAuditEntry)
{
+ if (teneoAuditEntry == null)
+ {
+ return null;
+ }
final HibernateStoreAccessor storeAccessor = HibernateThreadContext.getCurrentStoreAccessor();
- final EClass domainEClass = getAuditHandler().getModelElement(teneoAuditEntry.eClass());
+ final EClass domainEClass = getCDOAuditHandler().getModelElement(teneoAuditEntry.eClass());
final CDOID cdoID = HibernateUtil.getInstance().convertStringToCDOID(teneoAuditEntry.getTeneo_object_id());
- final InternalCDORevision revision = hibernateStore.createRevision(domainEClass, cdoID);
- revision.setBranchPoint(storeAccessor.getStore().getMainBranchHead().getBranch()
- .getPoint(teneoAuditEntry.getTeneo_start()));
- if (teneoAuditEntry.getTeneo_end() > 0)
+ final InternalCDORevision revision;
+ if (teneoAuditEntry.getTeneo_audit_kind() == TeneoAuditKind.DELETE)
{
- revision.setRevised(teneoAuditEntry.getTeneo_end());
+ revision = new DetachedCDORevision(domainEClass, cdoID, hibernateStore.getRepository().getBranchManager()
+ .getMainBranch(), new Long(teneoAuditEntry.getTeneo_object_version()).intValue(),
+ teneoAuditEntry.getTeneo_start(), CDOBranchPoint.UNSPECIFIED_DATE);
+ revision.setRevised(CDOBranchPoint.UNSPECIFIED_DATE);
+ }
+ else
+ {
+ revision = hibernateStore.createRevision(domainEClass, cdoID);
+ revision.setVersion(new Long(teneoAuditEntry.getTeneo_object_version()).intValue());
+ revision.setBranchPoint(storeAccessor.getStore().getMainBranchHead().getBranch()
+ .getPoint(teneoAuditEntry.getTeneo_start()));
+ if (teneoAuditEntry.getTeneo_end() > 0)
+ {
+ revision.setRevised(teneoAuditEntry.getTeneo_end());
+ }
+ else
+ {
+ revision.setRevised(CDOBranchPoint.UNSPECIFIED_DATE);
+ }
+ convertContent(teneoAuditEntry, revision);
}
- convertContent(teneoAuditEntry, revision);
return revision;
}
@@ -161,7 +192,7 @@ public class HibernateAuditHandler
public List<?> getCDOResources(Session session, CDOID folderId, long timeStamp)
{
- final AuditHandler auditHandler = getAuditHandler();
+ final AuditHandler auditHandler = getCDOAuditHandler();
final EClass auditEClass = auditHandler.getAuditingModelElement(EresourcePackage.eINSTANCE.getCDOResourceNode());
final String entityName = cdoDataStore.toEntityName(auditEClass);
return getCDOResources(session, folderId, timeStamp, entityName);
@@ -169,7 +200,7 @@ public class HibernateAuditHandler
public List<?> getCDOResources(Session session, CDOID folderId, long timeStamp, String entityName)
{
- final AuditHandler auditHandler = getAuditHandler();
+ final AuditHandler auditHandler = getCDOAuditHandler();
String idStr = null;
if (folderId != null)
{
@@ -190,19 +221,19 @@ public class HibernateAuditHandler
return qry.list();
}
- public List<CDORevision> handleRevisionsByEClass(Session session, EClass eClass, CDORevisionHandler handler,
- long timeStamp)
+ public void handleRevisionsByEClass(Session session, EClass eClass, CDORevisionHandler handler, long timeStamp)
{
AuditVersionProvider auditVersionProvider = cdoDataStore.getAuditVersionProvider();
auditVersionProvider.setSession(session);
- final List<TeneoAuditEntry> teneoAuditEntries = auditVersionProvider.getAllAuditEntries(eClass, timeStamp);
- final List<CDORevision> revisions = new ArrayList<CDORevision>();
+ final List<TeneoAuditEntry> teneoAuditEntries = auditVersionProvider.getSpecificAuditEntries(eClass, timeStamp);
for (TeneoAuditEntry teneoAuditEntry : teneoAuditEntries)
{
final CDORevision cdoRevision = getCDORevision(session, teneoAuditEntry);
- handler.handleRevision(cdoRevision);
+ if (!handler.handleRevision(cdoRevision))
+ {
+ return;
+ }
}
- return revisions;
}
public HbDataStore getCdoDataStore()
diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateStoreAccessor.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateStoreAccessor.java
index 3210809625..b84818c373 100644
--- a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateStoreAccessor.java
+++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateStoreAccessor.java
@@ -367,14 +367,15 @@ public class HibernateStoreAccessor extends StoreAccessor implements IHibernateS
return null;
}
- if (getStore().isAuditing() && branchPoint.getTimeStamp() != 0)
+ if (getStore().getHibernateAuditHandler().getCDOAuditHandler().isAudited(id) && getStore().isAuditing()
+ && branchPoint.getTimeStamp() != 0)
{
InternalCDORevision revision = getStore().getHibernateAuditHandler().readRevision(getHibernateSession(), id,
branchPoint.getTimeStamp());
// found one, use it
- if (revision != null)
+ if (revision != null && !(revision instanceof DetachedCDORevision))
{
- revision.setBranchPoint(getStore().getMainBranchHead());
+ revision.setBranchPoint(branchPoint);
return revision;
}
}
@@ -529,7 +530,10 @@ public class HibernateStoreAccessor extends StoreAccessor implements IHibernateS
final Query query = session.createQuery("select e from " + getStore().getEntityName(eClass) + " e");
for (Object o : query.list())
{
- handler.handleRevision((CDORevision)o);
+ if (!handler.handleRevision((CDORevision)o))
+ {
+ return;
+ }
}
}
finally
@@ -539,15 +543,28 @@ public class HibernateStoreAccessor extends StoreAccessor implements IHibernateS
}
/**
- * Not supported by the Hibernate Store, auditing is not supported. Currently ignores the branchVersion and calls the
- * {@readRevision(CDOID, CDOBranchPoint, int, CDORevisionCacheAdder)} .
+ * @see #readRevision(CDOID, CDOBranchPoint, int, CDORevisionCacheAdder)
*/
public InternalCDORevision readRevisionByVersion(CDOID id, CDOBranchVersion branchVersion, int listChunk,
CDORevisionCacheAdder cache)
{
- InternalCDORevision revision = readRevision(id, branchVersion.getBranch().getPoint(System.currentTimeMillis()),
- listChunk, cache);
- if (revision != null)
+ InternalCDORevision revision = null;
+ if (getStore().getHibernateAuditHandler().getCDOAuditHandler().isAudited(id))
+ {
+ revision = getStore().getHibernateAuditHandler().readRevisionByVersion(getHibernateSession(), id,
+ branchVersion.getVersion());
+ }
+ else
+ {
+ revision = readRevision(id, branchVersion.getBranch().getPoint(System.currentTimeMillis()), listChunk, cache);
+ if (revision != null)
+ {
+ // otherwise CDO gets confused and we get wrong version numbers later
+ revision.setVersion(branchVersion.getVersion());
+ }
+ }
+
+ if (revision != null && !(revision instanceof DetachedCDORevision))
{
revision.freeze();
}
@@ -760,6 +777,9 @@ public class HibernateStoreAccessor extends StoreAccessor implements IHibernateS
final Session session = getNewHibernateSession(false);
session.setDefaultReadOnly(false);
+ // decrement version, hibernate will increment it
+ decrementVersions(context);
+
// order is 1) insert, 2) update and then delete
// this order is the most stable! Do not change it without testing
@@ -790,12 +810,18 @@ public class HibernateStoreAccessor extends StoreAccessor implements IHibernateS
{
final String entityName = HibernateUtil.getInstance().getEntityName(revision.getID());
session.merge(entityName, revision);
+
if (TRACER.isEnabled())
{
TRACER.trace("Updated Object " + revision.getEClass().getName() + " id: " + revision.getID()); //$NON-NLS-1$ //$NON-NLS-2$
}
}
+ // and increment the versions again so that the objects are cached correctly
+ // note that this is needed because above a merge is done and not a
+ // saveupdate, so hibernate does not update the version back in the revision
+ incrementVersions(context);
+
session.flush();
// delete all objects
@@ -869,6 +895,31 @@ public class HibernateStoreAccessor extends StoreAccessor implements IHibernateS
monitor.done();
}
+ // set the version one back, hibernate will update it
+ private void decrementVersions(CommitContext context)
+ {
+ for (InternalCDORevision revision : context.getNewObjects())
+ {
+ revision.setVersion(revision.getVersion() - 1);
+ }
+ for (InternalCDORevision revision : context.getDirtyObjects())
+ {
+ revision.setVersion(revision.getVersion() - 1);
+ }
+ }
+
+ private void incrementVersions(CommitContext context)
+ {
+ for (InternalCDORevision revision : context.getNewObjects())
+ {
+ revision.setVersion(1);
+ }
+ for (InternalCDORevision revision : context.getDirtyObjects())
+ {
+ revision.setVersion(revision.getVersion() + 1);
+ }
+ }
+
private void repairContainerIDs(List<InternalCDORevision> repairContainerIDs, Session session)
{
for (InternalCDORevision revision : repairContainerIDs)
diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDORevisionTuplizer.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDORevisionTuplizer.java
index 0299f00555..b291702eaf 100644
--- a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDORevisionTuplizer.java
+++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDORevisionTuplizer.java
@@ -12,6 +12,7 @@
package org.eclipse.emf.cdo.server.internal.hibernate.tuplizer;
import org.eclipse.emf.cdo.common.model.EMFUtil;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.eresource.EresourcePackage;
import org.eclipse.emf.cdo.server.internal.hibernate.CDOHibernateConstants;
import org.eclipse.emf.cdo.server.internal.hibernate.HibernateStore;
@@ -378,4 +379,14 @@ public class CDORevisionTuplizer extends AbstractEntityTuplizer
{
return null;
}
+
+ @Override
+ public Object getVersion(Object entity) throws HibernateException
+ {
+ if (entity instanceof CDORevision)
+ {
+ return ((CDORevision)entity).getVersion();
+ }
+ return super.getVersion(entity);
+ }
}
diff --git a/plugins/org.eclipse.emf.cdo.tests.hibernate/src/org/eclipse/emf/cdo/tests/hibernate/AllTestsHibernate.java b/plugins/org.eclipse.emf.cdo.tests.hibernate/src/org/eclipse/emf/cdo/tests/hibernate/AllTestsHibernate.java
index 27e7683562..8f7d4f46c2 100644
--- a/plugins/org.eclipse.emf.cdo.tests.hibernate/src/org/eclipse/emf/cdo/tests/hibernate/AllTestsHibernate.java
+++ b/plugins/org.eclipse.emf.cdo.tests.hibernate/src/org/eclipse/emf/cdo/tests/hibernate/AllTestsHibernate.java
@@ -36,6 +36,7 @@ import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_279982_Test;
import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_303466_Test;
import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_306998_Test;
import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_322804_Test;
+import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_329254_Test;
import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_334995_Test;
import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_347964_Test;
import org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_351393_Test;
@@ -75,8 +76,8 @@ public class AllTestsHibernate extends AllConfigs
@Override
protected void initTestClasses(List<Class<? extends ConfigTest>> testClasses, IScenario scenario)
{
- testClasses.clear();
- // testClasses.add(Bugzilla_306998_Test.class);
+ // testClasses.clear();
+ // testClasses.add(RevisionDeltaTest.class);
// if (true)
// {
// return;
@@ -109,6 +110,8 @@ public class AllTestsHibernate extends AllConfigs
if (scenario.getCapabilities().contains(IRepositoryConfig.CAPABILITY_AUDITING))
{
+ testClasses.add(CDOObjectHistoryTest.class);
+
// the security model inherits from the ecore model
// not so well supported for now
testClasses.remove(SecurityManagerTest.class);
@@ -122,6 +125,8 @@ public class AllTestsHibernate extends AllConfigs
}
else
{
+ testClasses.remove(Bugzilla_329254_Test.class);
+ testClasses.remove(Hibernate_Bugzilla_329254_Test.class);
testClasses.remove(CommitInfoTest.class);
}
@@ -306,4 +311,15 @@ public class AllTestsHibernate extends AllConfigs
}
}
+
+ public static class Hibernate_Bugzilla_329254_Test extends Bugzilla_329254_Test
+ {
+
+ // does not work for non audited cases
+ @Override
+ public void testCommitTimeStampUpdateOnError() throws Exception
+ {
+ }
+
+ }
}
diff --git a/plugins/org.eclipse.emf.cdo.tests.hibernate/src/org/eclipse/emf/cdo/tests/hibernate/CDOObjectHistoryTest.java b/plugins/org.eclipse.emf.cdo.tests.hibernate/src/org/eclipse/emf/cdo/tests/hibernate/CDOObjectHistoryTest.java
new file mode 100644
index 0000000000..0071f8fc8d
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.tests.hibernate/src/org/eclipse/emf/cdo/tests/hibernate/CDOObjectHistoryTest.java
@@ -0,0 +1,351 @@
+/*
+ * Copyright (c) 2004 - 2012 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:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.tests.hibernate;
+
+import org.eclipse.emf.cdo.CDOObject;
+import org.eclipse.emf.cdo.CDOObjectHistory;
+import org.eclipse.emf.cdo.common.commit.CDOCommitHistory;
+import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
+import org.eclipse.emf.cdo.common.revision.CDOIDAndVersion;
+import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.common.revision.CDORevisionKey;
+import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
+import org.eclipse.emf.cdo.common.revision.delta.CDOSetFeatureDelta;
+import org.eclipse.emf.cdo.eresource.CDOResource;
+import org.eclipse.emf.cdo.eresource.EresourcePackage;
+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.ConfigTest.Requires;
+import org.eclipse.emf.cdo.tests.legacy.model1.Model1Package;
+import org.eclipse.emf.cdo.tests.model1.Company;
+import org.eclipse.emf.cdo.transaction.CDOTransaction;
+import org.eclipse.emf.cdo.view.CDOView;
+
+import org.eclipse.net4j.util.concurrent.ConcurrencyUtil;
+import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
+
+import java.util.List;
+
+/**
+ * @author Martin Taal
+ * @author Eike Stepper
+ */
+@Requires(IRepositoryConfig.CAPABILITY_AUDITING)
+public class CDOObjectHistoryTest extends AbstractCDOTest
+{
+ protected CDOSession session1;
+
+ private boolean finishedLoadingHistory = false;
+
+ @Override
+ protected void doTearDown() throws Exception
+ {
+ LifecycleUtil.deactivate(session1);
+ session1 = null;
+ super.doTearDown();
+ }
+
+ protected CDOSession openSession1()
+ {
+ session1 = openSession();
+ return session1;
+ }
+
+ protected void closeSession1()
+ {
+ session1.close();
+ }
+
+ protected CDOSession openSession2()
+ {
+ return openSession();
+ }
+
+ public void testChangedAudit() throws Exception
+ {
+ CDOSession session = openSession1();
+ CDOTransaction transaction = session.openTransaction();
+ CDOResource resource = transaction.createResource(getResourcePath("/res1"));
+
+ Company company = getModel1Factory().createCompany();
+ company.setName("ESC");
+ resource.getContents().add(company);
+ long commitTime1 = transaction.commit().getTimeStamp();
+ assertEquals(true, session.getRepositoryInfo().getCreationTime() < commitTime1);
+ assertEquals("ESC", company.getName());
+
+ company.setName("Sympedia");
+ long commitTime2 = transaction.commit().getTimeStamp();
+ assertEquals(true, commitTime1 < commitTime2);
+ assertEquals(true, session.getRepositoryInfo().getCreationTime() < commitTime2);
+ assertEquals("Sympedia", company.getName());
+
+ company.setName("Eclipse");
+ long commitTime3 = transaction.commit().getTimeStamp();
+ assertEquals(true, commitTime2 < commitTime3);
+ assertEquals(true, session.getRepositoryInfo().getCreationTime() < commitTime2);
+ assertEquals("Eclipse", company.getName());
+
+ resource.getContents().remove(company);
+ long commitTime4 = transaction.commit().getTimeStamp();
+
+ closeSession1();
+ session = openSession2();
+
+ CDOView audit = session.openView(commitTime1);
+ {
+ CDOResource auditResource = audit.getResource(getResourcePath("/res1"));
+ Company auditCompany = (Company)auditResource.getContents().get(0);
+ assertEquals("ESC", auditCompany.getName());
+
+ final CDOObjectHistory cdoObjectHistory = getCDOObjectHistory(audit, auditCompany);
+ assertEquals(1, cdoObjectHistory.getElements().length);
+ for (CDOCommitInfo cdoCommitInfo : cdoObjectHistory.getElements())
+ {
+ if (cdoCommitInfo.getTimeStamp() == commitTime1)
+ {
+ checkCommitInfo1(cdoCommitInfo);
+ }
+ else
+ {
+ fail();
+ }
+ }
+ audit.close();
+ }
+
+ audit = session.openView(commitTime2);
+ {
+ CDOResource auditResource = audit.getResource(getResourcePath("/res1"));
+ Company auditCompany = (Company)auditResource.getContents().get(0);
+ assertEquals("Sympedia", auditCompany.getName());
+
+ final CDOObjectHistory cdoObjectHistory = getCDOObjectHistory(audit, auditCompany);
+ assertEquals(2, cdoObjectHistory.getElements().length);
+ for (CDOCommitInfo cdoCommitInfo : cdoObjectHistory.getElements())
+ {
+ if (cdoCommitInfo.getTimeStamp() == commitTime1)
+ {
+ checkCommitInfo1(cdoCommitInfo);
+ }
+ else if (cdoCommitInfo.getTimeStamp() == commitTime2)
+ {
+ checkCommitInfo2(cdoCommitInfo);
+ }
+ else
+ {
+ fail();
+ }
+ }
+ audit.close();
+ }
+
+ audit = session.openView(commitTime3);
+ {
+ CDOResource auditResource = audit.getResource(getResourcePath("/res1"));
+ Company auditCompany = (Company)auditResource.getContents().get(0);
+ assertEquals("Eclipse", auditCompany.getName());
+
+ final CDOObjectHistory cdoObjectHistory = getCDOObjectHistory(audit, auditCompany);
+ assertEquals(3, cdoObjectHistory.getElements().length);
+ for (CDOCommitInfo cdoCommitInfo : cdoObjectHistory.getElements())
+ {
+ if (cdoCommitInfo.getTimeStamp() == commitTime1)
+ {
+ checkCommitInfo1(cdoCommitInfo);
+ }
+ else if (cdoCommitInfo.getTimeStamp() == commitTime2)
+ {
+ checkCommitInfo2(cdoCommitInfo);
+ }
+ else if (cdoCommitInfo.getTimeStamp() == commitTime3)
+ {
+ checkCommitInfo3(cdoCommitInfo);
+ }
+ else
+ {
+ fail();
+ }
+ }
+ audit.close();
+ }
+
+ audit = session.openView(commitTime4);
+ {
+ final CDOCommitHistory cdoCommitHistory = getCDOCommitHistory(audit);
+ assertEquals(5, cdoCommitHistory.getElements().length);
+ for (CDOCommitInfo cdoCommitInfo : cdoCommitHistory.getElements())
+ {
+ if (cdoCommitInfo.getTimeStamp() == commitTime1)
+ {
+ checkCommitInfo1(cdoCommitInfo);
+ }
+ else if (cdoCommitInfo.getTimeStamp() == commitTime2)
+ {
+ checkCommitInfo2(cdoCommitInfo);
+ }
+ else if (cdoCommitInfo.getTimeStamp() == commitTime3)
+ {
+ checkCommitInfo3(cdoCommitInfo);
+ }
+ else if (cdoCommitInfo.getTimeStamp() == commitTime4)
+ {
+ checkCommitInfo4(cdoCommitInfo);
+ }
+ else if (cdoCommitInfo.getComment() != null && cdoCommitInfo.getComment().equals("<initialize>"))
+ {
+ // as expected
+ }
+ else
+ {
+ fail();
+ }
+ }
+ audit.close();
+ }
+
+ session.close();
+ }
+
+ private void checkCommitInfo1(CDOCommitInfo cdoCommitInfo)
+ {
+ final List<CDOIDAndVersion> newObjects = cdoCommitInfo.getNewObjects();
+ final List<CDORevisionKey> changedObjects = cdoCommitInfo.getChangedObjects();
+ final List<CDOIDAndVersion> detachedObjects = cdoCommitInfo.getDetachedObjects();
+ assertEquals(0, detachedObjects.size());
+ assertEquals(3, newObjects.size());
+ assertEquals(1, changedObjects.size());
+ for (Object o : changedObjects)
+ {
+ final CDORevisionDelta cdoRevisionDelta = (CDORevisionDelta)o;
+ final CDOFeatureDelta cdoFeatureDelta = cdoRevisionDelta.getFeatureDelta(EresourcePackage.eINSTANCE
+ .getCDOResource_Contents());
+ assertNotNull(cdoFeatureDelta);
+ assertEquals(CDOFeatureDelta.Type.LIST, cdoFeatureDelta.getType());
+ }
+ int resourceCnt = 0;
+ int resourceFolderCnt = 0;
+ int companyCnt = 0;
+ for (Object o : newObjects)
+ {
+ final CDORevision cdoRevision = (CDORevision)o;
+ if (cdoRevision.getEClass().getName().equals(Model1Package.eINSTANCE.getCompany().getName()))
+ {
+ companyCnt++;
+ }
+ if (cdoRevision.getEClass() == EresourcePackage.eINSTANCE.getCDOResource())
+ {
+ resourceCnt++;
+ }
+ if (cdoRevision.getEClass() == EresourcePackage.eINSTANCE.getCDOResourceFolder())
+ {
+ resourceFolderCnt++;
+ }
+ }
+ assertEquals(1, companyCnt);
+ assertEquals(1, resourceCnt);
+ assertEquals(1, resourceFolderCnt);
+ }
+
+ private void checkCommitInfo2(CDOCommitInfo cdoCommitInfo)
+ {
+ final List<CDOIDAndVersion> newObjects = cdoCommitInfo.getNewObjects();
+ final List<CDORevisionKey> changedObjects = cdoCommitInfo.getChangedObjects();
+ final List<CDOIDAndVersion> detachedObjects = cdoCommitInfo.getDetachedObjects();
+ assertEquals(0, detachedObjects.size());
+ assertEquals(0, newObjects.size());
+ assertEquals(1, changedObjects.size());
+ for (Object o : changedObjects)
+ {
+ final CDORevisionDelta cdoRevisionDelta = (CDORevisionDelta)o;
+ final CDOSetFeatureDelta cdoFeatureDelta = (CDOSetFeatureDelta)cdoRevisionDelta.getFeatureDelta(cdoRevisionDelta
+ .getEClass().getEStructuralFeature("name"));
+ assertNotNull(cdoFeatureDelta);
+ assertEquals("Sympedia", cdoFeatureDelta.getValue());
+ }
+ }
+
+ private void checkCommitInfo3(CDOCommitInfo cdoCommitInfo)
+ {
+ final List<CDOIDAndVersion> newObjects = cdoCommitInfo.getNewObjects();
+ final List<CDORevisionKey> changedObjects = cdoCommitInfo.getChangedObjects();
+ final List<CDOIDAndVersion> detachedObjects = cdoCommitInfo.getDetachedObjects();
+ assertEquals(0, detachedObjects.size());
+ assertEquals(0, newObjects.size());
+ assertEquals(1, changedObjects.size());
+ for (Object o : changedObjects)
+ {
+ final CDORevisionDelta cdoRevisionDelta = (CDORevisionDelta)o;
+ final CDOSetFeatureDelta cdoFeatureDelta = (CDOSetFeatureDelta)cdoRevisionDelta.getFeatureDelta(cdoRevisionDelta
+ .getEClass().getEStructuralFeature("name"));
+ assertNotNull(cdoFeatureDelta);
+ assertEquals("Eclipse", cdoFeatureDelta.getValue());
+ }
+ }
+
+ private void checkCommitInfo4(CDOCommitInfo cdoCommitInfo)
+ {
+ final List<CDOIDAndVersion> newObjects = cdoCommitInfo.getNewObjects();
+ final List<CDORevisionKey> changedObjects = cdoCommitInfo.getChangedObjects();
+ final List<CDOIDAndVersion> detachedObjects = cdoCommitInfo.getDetachedObjects();
+ assertEquals(1, detachedObjects.size());
+ assertEquals(0, newObjects.size());
+ assertEquals(1, changedObjects.size());
+ for (Object o : changedObjects)
+ {
+ final CDORevisionDelta cdoRevisionDelta = (CDORevisionDelta)o;
+ final CDOFeatureDelta cdoFeatureDelta = cdoRevisionDelta.getFeatureDelta(EresourcePackage.eINSTANCE
+ .getCDOResource_Contents());
+ assertNotNull(cdoFeatureDelta);
+ assertEquals(CDOFeatureDelta.Type.LIST, cdoFeatureDelta.getType());
+ }
+ }
+
+ private synchronized CDOObjectHistory getCDOObjectHistory(CDOView audit, Object object)
+ {
+ CDOObjectHistory cdoObjectHistory = audit.getHistory((CDOObject)object);
+
+ cdoObjectHistory.triggerLoad();
+ long startTime = System.currentTimeMillis();
+ while (cdoObjectHistory.isLoading())
+ {
+ ConcurrencyUtil.sleep(10);
+
+ // waited too long
+ if (System.currentTimeMillis() - startTime > 5000)
+ {
+ throw new IllegalStateException("commit info could not be loaded");
+ }
+ }
+ return cdoObjectHistory;
+ }
+
+ private synchronized CDOCommitHistory getCDOCommitHistory(CDOView audit)
+ {
+ CDOCommitHistory cdoCommitHistory = audit.getHistory();
+
+ cdoCommitHistory.triggerLoad();
+ long startTime = System.currentTimeMillis();
+ while (cdoCommitHistory.isLoading())
+ {
+ ConcurrencyUtil.sleep(10);
+
+ // waited too long
+ if (System.currentTimeMillis() - startTime > 5000)
+ {
+ throw new IllegalStateException("commit info could not be loaded");
+ }
+ }
+ return cdoCommitHistory;
+ }
+}

Back to the top