diff options
author | Martin Taal | 2012-11-25 15:57:21 +0000 |
---|---|---|
committer | Martin Taal | 2012-11-25 15:57:21 +0000 |
commit | d2c6b937b688bd4e5c66d5c54aa7ca6be7c05cb5 (patch) | |
tree | 0b2635483958861a1a4c52101d8ac0e0546da467 /plugins/org.eclipse.emf.cdo.server.hibernate | |
parent | afd69f07ced375df999e18f251d5a2747cc2a050 (diff) | |
download | cdo-d2c6b937b688bd4e5c66d5c54aa7ca6be7c05cb5.tar.gz cdo-d2c6b937b688bd4e5c66d5c54aa7ca6be7c05cb5.tar.xz cdo-d2c6b937b688bd4e5c66d5c54aa7ca6be7c05cb5.zip |
Support auditing in the hibernate store
Diffstat (limited to 'plugins/org.eclipse.emf.cdo.server.hibernate')
10 files changed, 377 insertions, 78 deletions
diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.cdo.server.hibernate/META-INF/MANIFEST.MF index 10a296d944..55c3e8bcd9 100644 --- a/plugins/org.eclipse.emf.cdo.server.hibernate/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/META-INF/MANIFEST.MF @@ -33,6 +33,7 @@ Import-Package: org.apache.log4j;version="[1.2.12, 1.3.0)", org.hibernate.engine;version="[4.0.0,5.0.0)", org.hibernate.id;version="[4.0.0,5.0.0)", org.hibernate.mapping;version="[4.0.0,5.0.0)", + org.hibernate.metadata;version="[4.0.0,5.0.0)", org.hibernate.persister.entity;version="[4.0.0,5.0.0)", org.hibernate.property;version="[4.0.0,5.0.0)", org.hibernate.proxy;version="[4.0.0,5.0.0)", 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 7a74641c6b..e06d319548 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 @@ -17,11 +17,15 @@ 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; +import org.eclipse.emf.common.util.Enumerator; import org.eclipse.emf.ecore.EAttribute; import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EEnum; +import org.eclipse.emf.ecore.EEnumLiteral; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.EcorePackage; import org.eclipse.emf.ecore.util.ExtendedMetaData; import org.eclipse.emf.ecore.util.FeatureMapUtil; import org.eclipse.emf.teneo.hibernate.auditing.AuditHandler; @@ -159,13 +163,23 @@ public class CDOAuditHandler extends AuditHandler { for (Object value : (Collection<?>)source.getList(sourceEFeature)) { - ((Collection<Object>)auditEntry.eGet(targetEFeature)).add(convertValue(targetEFeature, value)); + ((Collection<Object>)auditEntry.eGet(targetEFeature)).add(convertValue(sourceEFeature, targetEFeature, + value)); } } } else { - auditEntry.eSet(targetEFeature, convertValue(targetEFeature, source.getValue(sourceEFeature))); + // not set + if (sourceEFeature.isUnsettable() && source.getValue(sourceEFeature) == null) + { + auditEntry.eUnset(targetEFeature); + } + else + { + auditEntry.eSet(targetEFeature, + convertValue(sourceEFeature, targetEFeature, source.getValue(sourceEFeature))); + } } } } @@ -222,14 +236,57 @@ public class CDOAuditHandler extends AuditHandler return HibernateUtil.getInstance().convertCDOIDToString((CDOID)id); } - @Override - public Object convertValue(EStructuralFeature eFeature, Object value) + public Object convertValue(EStructuralFeature sourceEFeature, EStructuralFeature eFeature, Object value) { if (value == CDORevisionData.NIL) { return null; } + if (value instanceof EEnumLiteral) + { + return ((EEnumLiteral)value).getLiteral(); + } + if (value instanceof Enumerator) + { + return ((Enumerator)value).getLiteral(); + } + + if (sourceEFeature.getEType() instanceof EEnum && value instanceof Integer) + { + final int ordinal = (Integer)value; + final EEnum eeNum = (EEnum)sourceEFeature.getEType(); + if (eeNum.getInstanceClass() != null && eeNum.getInstanceClass().isEnum()) + { + final Object[] constants = eeNum.getInstanceClass().getEnumConstants(); + for (Object constant : constants) + { + if (constant instanceof Enumerator) + { + final Enumerator enumerator = (Enumerator)constant; + if (enumerator.getValue() == ordinal) + { + return enumerator.getLiteral(); + } + } + } + return ((Enum<?>)constants[ordinal]).name(); + } + return eeNum.getEEnumLiteral((Integer)value).getLiteral(); + } + return super.convertValue(eFeature, value); } + // map all enums as string + @Override + protected EStructuralFeature createEAttribute(EAttribute eAttribute) + { + final EStructuralFeature eFeature = super.createEAttribute(eAttribute); + if (eFeature.getEType() instanceof EEnum) + { + eFeature.setEType(EcorePackage.eINSTANCE.getEString()); + } + return eFeature; + } + } 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 93439fa1d1..4343c49aa1 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 @@ -24,6 +24,7 @@ import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; import org.eclipse.emf.common.util.Enumerator; import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EEnum; import org.eclipse.emf.ecore.EEnumLiteral; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; @@ -86,7 +87,13 @@ public class HibernateAuditHandler { AuditVersionProvider auditVersionProvider = cdoDataStore.getAuditVersionProvider(); auditVersionProvider.setSession(session); - final TeneoAuditEntry auditEntry = auditVersionProvider.getAuditEntry(eClass, id, timeStamp); + long useTimeStamp = timeStamp; + if (useTimeStamp == 0) + { + // use the last revision + useTimeStamp = Long.MAX_VALUE; + } + final TeneoAuditEntry auditEntry = auditVersionProvider.getAuditEntry(eClass, id, useTimeStamp); return getCDORevision(session, auditEntry); } @@ -165,6 +172,12 @@ public class HibernateAuditHandler cdoRevision.setContainerID(HibernateUtil.getInstance().convertStringToCDOID(auditEntry.getTeneo_container_id())); cdoRevision.setContainingFeatureID(auditEntry.getTeneo_container_feature_id()); } + + final String resourceID = auditEntry.getTeneo_resourceid(); + if (resourceID != null) + { + cdoRevision.setResourceID(HibernateUtil.getInstance().convertStringToCDOID(resourceID)); + } } private Object convertValue(EStructuralFeature targetEFeature, Object value) @@ -187,6 +200,10 @@ public class HibernateAuditHandler { return ((EEnumLiteral)value).getValue(); } + if (value instanceof String && targetEFeature.getEType() instanceof EEnum) + { + return ((EEnum)targetEFeature.getEType()).getEEnumLiteral((String)value).getValue(); + } return value; } @@ -229,6 +246,13 @@ public class HibernateAuditHandler for (TeneoAuditEntry teneoAuditEntry : teneoAuditEntries) { final CDORevision cdoRevision = getCDORevision(session, teneoAuditEntry); + + // if a subclass ignore + if (cdoRevision.getEClass() != eClass) + { + continue; + } + if (!handler.handleRevision(cdoRevision)) { return; diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateQueryHandler.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateQueryHandler.java index 2f3478fdb8..9619becaa0 100644 --- a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateQueryHandler.java +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateQueryHandler.java @@ -22,12 +22,16 @@ import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.teneo.hibernate.auditing.model.teneoauditing.TeneoAuditEntry; import org.hibernate.Hibernate; import org.hibernate.Query; +import org.hibernate.ScrollMode; +import org.hibernate.ScrollableResults; import org.hibernate.Session; import java.io.Serializable; +import java.lang.reflect.Array; /** * Implements server side HQL query execution.. @@ -50,6 +54,8 @@ public class HibernateQueryHandler implements IQueryHandler private HibernateStoreAccessor hibernateStoreAccessor; + private HibernateAuditHandler hibernateAuditHandler; + /** * Executes hql queries. Gets the session from the {@link HibernateStoreAccessor} creates a hibernate query and sets * the parameters taken from the {@link CDOQueryInfo#getParameters()}. Takes into account the @@ -139,25 +145,74 @@ public class HibernateQueryHandler implements IQueryHandler query.setMaxResults(info.getMaxResults()); } + final ScrollableResults scroller = query.scroll(ScrollMode.FORWARD_ONLY); + // and go for the query // future extension: support iterate, scroll through a parameter - for (Object o : query.list()) + int i = 0; + try { - final boolean addOneMore = context.addResult(o); - if (cacheResults && o instanceof CDORevision) - { - addToRevisionCache((CDORevision)o); - } - if (o instanceof InternalCDORevision) + while (scroller.next()) { - ((InternalCDORevision)o).freeze(); + Object[] os = scroller.get(); + Object o; + if (os.length == 1) + { + o = handleAuditEntries(os[0]); + } + else + { + o = handleAuditEntries(os); + } + + final boolean addOneMore = context.addResult(o); + if (cacheResults && o instanceof CDORevision) + { + addToRevisionCache((CDORevision)o); + } + if (o instanceof InternalCDORevision) + { + ((InternalCDORevision)o).freeze(); + } + + // clear the session every 1000 results or so + if (i++ % 1000 == 0) + { + session.clear(); + } + + if (!addOneMore) + { + return; + } } + } + finally + { + scroller.close(); + } + } - if (!addOneMore) + private Object handleAuditEntries(Object o) + { + if (o.getClass().isArray()) + { + for (int i = 0; i < Array.getLength(o); i++) { - return; + Array.set(o, i, handleAuditEntry(Array.get(o, i))); } + return o; + } + return handleAuditEntry(o); + } + + private Object handleAuditEntry(Object o) + { + if (!(o instanceof TeneoAuditEntry)) + { + return o; } + return hibernateAuditHandler.convertAuditEntryToCDORevision((TeneoAuditEntry)o); } private void addToRevisionCache(CDORevision revision) @@ -213,5 +268,6 @@ public class HibernateQueryHandler implements IQueryHandler public void setHibernateStoreAccessor(HibernateStoreAccessor hibernateStoreAccessor) { this.hibernateStoreAccessor = hibernateStoreAccessor; + hibernateAuditHandler = hibernateStoreAccessor.getStore().getHibernateAuditHandler(); } } diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateStore.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateStore.java index 49a01fddbd..0cef05ac9a 100644 --- a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateStore.java +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/HibernateStore.java @@ -27,6 +27,7 @@ import org.eclipse.emf.cdo.server.hibernate.IHibernateStore; import org.eclipse.emf.cdo.server.internal.hibernate.bundle.OM; import org.eclipse.emf.cdo.server.internal.hibernate.tuplizer.CDOInterceptor; import org.eclipse.emf.cdo.server.internal.hibernate.tuplizer.CDOMergeEventListener; +import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; import org.eclipse.emf.cdo.spi.server.Store; import org.eclipse.emf.cdo.spi.server.StoreAccessorPool; @@ -50,6 +51,7 @@ import org.eclipse.emf.teneo.hibernate.HbDataStore; import org.eclipse.emf.teneo.hibernate.HbSessionDataStore; import org.eclipse.emf.teneo.hibernate.auditing.AuditHandler; import org.eclipse.emf.teneo.hibernate.auditing.AuditProcessHandler; +import org.eclipse.emf.teneo.hibernate.auditing.model.teneoauditing.TeneoAuditEntry; import org.eclipse.emf.teneo.hibernate.auditing.model.teneoauditing.TeneoauditingPackage; import org.eclipse.emf.teneo.hibernate.mapper.HibernateMappingGenerator; @@ -172,6 +174,11 @@ public class HibernateStore extends Store implements IHibernateStore return identifierPropertyNameByEntity.get(entityName); } + public boolean isMapped(EClass eClass) + { + return null != cdoDataStore.toEntityName(eClass); + } + public Properties getProperties() { if (properties == null || properties.isEmpty()) @@ -343,11 +350,11 @@ public class HibernateStore extends Store implements IHibernateStore } if (cdoDataStore.getPackageRegistry() instanceof TransactionPackageRegistry) { - setInteralPackageRegistry(); + setInternalPackageRegistry(); } } - private synchronized void setInteralPackageRegistry() + private synchronized void setInternalPackageRegistry() { cdoDataStore.setPackageRegistry(getRepository().getPackageRegistry(false)); } @@ -616,6 +623,12 @@ public class HibernateStore extends Store implements IHibernateStore final Properties props = new Properties(); props.putAll(getProperties()); props.remove(PersistenceOptions.PERSISTENCE_XML); + + if (!props.containsKey(PersistenceOptions.HANDLE_UNSET_AS_NULL)) + { + props.setProperty(PersistenceOptions.HANDLE_UNSET_AS_NULL, "true"); + } + cdoDataStore.setDataStoreProperties(props); Configuration hibernateConfiguration = cdoDataStore.getConfiguration(); @@ -730,7 +743,9 @@ public class HibernateStore extends Store implements IHibernateStore } epacks.add(dataStore.getAuditHandler().createAuditingEPackage(dataStore, EresourcePackage.eINSTANCE, getRepository().getPackageRegistry(), po)); + epacks.add(TeneoauditingPackage.eINSTANCE); + getRepository().getPackageRegistry().put(TeneoauditingPackage.eNS_URI, TeneoauditingPackage.eINSTANCE); // also register them all in the non-transaction registry @@ -757,6 +772,7 @@ public class HibernateStore extends Store implements IHibernateStore final HibernateMappingGenerator hmg = dataStore.getExtensionManager().getExtension(HibernateMappingGenerator.class); hmg.setPersistenceOptions(po); final String hbm = hmg.generateToString(paModel); + return hbm; } @@ -841,5 +857,34 @@ public class HibernateStore extends Store implements IHibernateStore AuditProcessHandler.setCurrentComment(null); } } + + @Override + protected void setContainerInfo(Session session, TeneoAuditEntry auditEntry, Object entity) + { + if (!(entity instanceof InternalCDORevision)) + { + return; + } + final InternalCDORevision cdoRevision = (InternalCDORevision)entity; + + // set the resource id + if (cdoRevision.getResourceID() != null) + { + auditEntry.setTeneo_resourceid(getAuditHandler().entityToIdString(session, cdoRevision.getResourceID())); + } + + if (cdoRevision.getContainerID() == null || cdoRevision.getContainerID() == CDOID.NULL) + { + return; + } + + auditEntry.setTeneo_container_id(getAuditHandler().entityToIdString(session, cdoRevision.getContainerID())); + auditEntry.setTeneo_container_feature_id(cdoRevision.getContainingFeatureID()); + } + } + + public HbSessionDataStore getCDODataStore() + { + return cdoDataStore; } } 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 1d9b94b5d4..b9a2e84d3b 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 @@ -63,12 +63,15 @@ import org.eclipse.net4j.util.om.monitor.OMMonitor; import org.eclipse.net4j.util.om.monitor.OMMonitor.Async; import org.eclipse.net4j.util.om.trace.ContextTracer; +import org.eclipse.emf.ecore.EAnnotation; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EClassifier; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.EcoreFactory; import org.eclipse.emf.teneo.Constants; +import org.eclipse.emf.teneo.PackageRegistryProvider; import org.eclipse.emf.teneo.hibernate.auditing.model.teneoauditing.TeneoAuditCommitInfo; import org.eclipse.emf.teneo.hibernate.auditing.model.teneoauditing.TeneoAuditEntry; import org.eclipse.emf.teneo.hibernate.auditing.model.teneoauditing.TeneoauditingPackage; @@ -114,6 +117,11 @@ public class HibernateStoreAccessor extends StoreAccessor implements IHibernateS private static final String NAME_EFEATURE_NAME = "name";//$NON-NLS-1$ + // used to tag an ereference + private static final String TENEO_MAPPED_SOURCE = "teneo.mapped"; + + private static final String TENEO_UNMAPPED_SOURCE = "teneo.unmapped"; + private Session hibernateSession; private boolean errorOccured; @@ -367,15 +375,13 @@ public class HibernateStoreAccessor extends StoreAccessor implements IHibernateS return null; } - if (getStore().getHibernateAuditHandler().getCDOAuditHandler().isAudited(id) && getStore().isAuditing() - && branchPoint.getTimeStamp() != 0) + if (getStore().isAuditing() && getStore().getHibernateAuditHandler().getCDOAuditHandler().isAudited(id)) { InternalCDORevision revision = getStore().getHibernateAuditHandler().readRevision(getHibernateSession(), id, branchPoint.getTimeStamp()); // found one, use it - if (revision != null && !(revision instanceof DetachedCDORevision)) + if (revision != null) { - revision.setBranchPoint(branchPoint); return revision; } } @@ -475,11 +481,18 @@ public class HibernateStoreAccessor extends StoreAccessor implements IHibernateS throw new UnsupportedOperationException(); } + // should only return revisions of the eclass itself and not of its subclasses. public void handleRevisions(EClass eClass, CDOBranch branch, long timeStamp, boolean exactTime, CDORevisionHandler handler) { + if (eClass != null) { + if (!getStore().isMapped(eClass)) + { + return; + } + handleRevisionsByEClass(eClass, handler, timeStamp); } else @@ -498,13 +511,8 @@ public class HibernateStoreAccessor extends StoreAccessor implements IHibernateS if (eClassifier instanceof EClass) { final EClass eClazz = (EClass)eClassifier; - try - { - getStore().getEntityName(eClazz); - } - catch (IllegalArgumentException ex) + if (!getStore().isMapped(eClazz)) { - // a non-mapped eclass continue; } handleRevisionsByEClass(eClazz, handler, timeStamp); @@ -531,7 +539,15 @@ public class HibernateStoreAccessor extends StoreAccessor implements IHibernateS final Query query = session.createQuery("select e from " + getStore().getEntityName(eClass) + " e"); for (Object o : query.list()) { - if (!handler.handleRevision((CDORevision)o)) + CDORevision cdoRevision = (CDORevision)o; + + // if a subclass ignore + if (cdoRevision.getEClass() != eClass) + { + continue; + } + + if (!handler.handleRevision(cdoRevision)) { return; } @@ -655,13 +671,31 @@ public class HibernateStoreAccessor extends StoreAccessor implements IHibernateS { final CDORevision revision = HibernateUtil.getInstance().getCDORevision(targetCdoId); final EClass targetEClass = context.getTargetObjects().get(targetCdoId); + + if (!getStore().isMapped(targetEClass)) + { + continue; + } + final String targetEntityName = getStore().getEntityName(targetEClass); final Map<EClass, List<EReference>> sourceCandidates = context.getSourceCandidates(); for (EClass sourceEClass : sourceCandidates.keySet()) { + + if (!getStore().isMapped(sourceEClass)) + { + continue; + } + final String sourceEntityName = getStore().getEntityName(sourceEClass); for (EReference eref : sourceCandidates.get(sourceEClass)) { + // handle transient ereferences + if (!isEReferenceMapped(session, sourceEntityName, eref)) + { + continue; + } + final String hql; if (eref.isMany()) { @@ -702,6 +736,38 @@ public class HibernateStoreAccessor extends StoreAccessor implements IHibernateS } } + private boolean isEReferenceMapped(Session session, String entityName, EReference eref) + { + // mapped + if (null != eref.getEAnnotation(TENEO_MAPPED_SOURCE)) + { + return true; + } + else + // not mapped + if (null != eref.getEAnnotation(TENEO_UNMAPPED_SOURCE)) + { + return false; + } + + // not computed yet + for (String propName : session.getSessionFactory().getClassMetadata(entityName).getPropertyNames()) + { + if (propName.equals(eref.getName())) + { + final EAnnotation eAnnotation = EcoreFactory.eINSTANCE.createEAnnotation(); + eAnnotation.setSource(TENEO_MAPPED_SOURCE); + eref.getEAnnotations().add(eAnnotation); + return true; + } + } + // not mapped + final EAnnotation eAnnotation = EcoreFactory.eINSTANCE.createEAnnotation(); + eAnnotation.setSource(TENEO_UNMAPPED_SOURCE); + eref.getEAnnotations().add(eAnnotation); + return false; + } + private CDOID getHibernateID(CDOID id) { if (!CDOIDUtil.isNull(id)) @@ -1271,11 +1337,13 @@ public class HibernateStoreAccessor extends StoreAccessor implements IHibernateS { PersistableListHolder.getInstance().clearListMapping(); HibernateThreadContext.setCommitContext(null); + PackageRegistryProvider.getInstance().setThreadPackageRegistry(null); } @Override protected void doActivate() throws Exception { + PackageRegistryProvider.getInstance().setThreadPackageRegistry(getStore().getRepository().getPackageRegistry()); } @Override diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOPropertyGetter.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOPropertyGetter.java index dd3fc4ef2f..4d6f074a72 100644 --- a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOPropertyGetter.java +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOPropertyGetter.java @@ -17,6 +17,7 @@ import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; import org.eclipse.emf.common.util.Enumerator; import org.eclipse.emf.ecore.EEnum; +import org.eclipse.emf.teneo.PersistenceOptions; import org.hibernate.HibernateException; import org.hibernate.engine.spi.SessionImplementor; @@ -39,6 +40,8 @@ public class CDOPropertyGetter extends CDOPropertyHandler implements Getter private final EEnum eEnum; + private boolean handleUnsetAsNull = false; + public CDOPropertyGetter(CDORevisionTuplizer tuplizer, String propertyName) { super(tuplizer, propertyName); @@ -78,12 +81,12 @@ public class CDOPropertyGetter extends CDOPropertyHandler implements Getter return null; } - if (getEStructuralFeature().isUnsettable()) + if (handleUnsetAsNull && getEStructuralFeature().isUnsettable()) { return null; } - if (isEEnum) + if (isEEnum || !handleUnsetAsNull) { // handle it a few lines lower value = getEStructuralFeature().getDefaultValue(); @@ -134,4 +137,11 @@ public class CDOPropertyGetter extends CDOPropertyHandler implements Getter { return Object.class; } + + @Override + public void setPersistenceOptions(PersistenceOptions persistenceOptions) + { + super.setPersistenceOptions(persistenceOptions); + handleUnsetAsNull = persistenceOptions.getHandleUnsetAsNull(); + } } diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOPropertyHandler.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOPropertyHandler.java index c4c2b63fe2..2888c26818 100644 --- a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOPropertyHandler.java +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOPropertyHandler.java @@ -16,6 +16,7 @@ import org.eclipse.emf.cdo.server.internal.hibernate.bundle.OM; import org.eclipse.net4j.util.om.trace.ContextTracer; import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.teneo.PersistenceOptions; /** * @author Martin Taal @@ -30,6 +31,8 @@ public abstract class CDOPropertyHandler private boolean virtualProperty; + private PersistenceOptions persistenceOptions; + public CDOPropertyHandler(CDORevisionTuplizer tuplizer, String propertyName) { this.tuplizer = tuplizer; @@ -85,4 +88,14 @@ public abstract class CDOPropertyHandler { return virtualProperty; } + + public PersistenceOptions getPersistenceOptions() + { + return persistenceOptions; + } + + public void setPersistenceOptions(PersistenceOptions persistenceOptions) + { + this.persistenceOptions = persistenceOptions; + } } diff --git a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOPropertySetter.java b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOPropertySetter.java index 41a92b7564..0363086f6e 100644 --- a/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOPropertySetter.java +++ b/plugins/org.eclipse.emf.cdo.server.hibernate/src/org/eclipse/emf/cdo/server/internal/hibernate/tuplizer/CDOPropertySetter.java @@ -20,6 +20,7 @@ import org.eclipse.emf.ecore.EAttribute; import org.eclipse.emf.ecore.EEnum; import org.eclipse.emf.ecore.EEnumLiteral; import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.teneo.PersistenceOptions; import org.hibernate.HibernateException; import org.hibernate.engine.spi.SessionFactoryImplementor; @@ -38,6 +39,8 @@ public class CDOPropertySetter extends CDOPropertyHandler implements Setter private final boolean convertByteArray; + private boolean handleUnsetAsNull = false; + public CDOPropertySetter(CDORevisionTuplizer tuplizer, String propertyName) { super(tuplizer, propertyName); @@ -110,7 +113,7 @@ public class CDOPropertySetter extends CDOPropertyHandler implements Setter { newValue = null; } - else if (getEStructuralFeature().isUnsettable()) + else if (handleUnsetAsNull && getEStructuralFeature().isUnsettable()) { newValue = null; } @@ -145,4 +148,12 @@ public class CDOPropertySetter extends CDOPropertyHandler implements Setter } return false; } + + @Override + public void setPersistenceOptions(PersistenceOptions persistenceOptions) + { + super.setPersistenceOptions(persistenceOptions); + handleUnsetAsNull = persistenceOptions.getHandleUnsetAsNull(); + } + } 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 b291702eaf..57d22d28a5 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 @@ -198,42 +198,52 @@ public class CDORevisionTuplizer extends AbstractEntityTuplizer { return mappedProperty.getGetter(mappedEntity.getMappedClass()); } - else if (mappedProperty == mappedEntity.getIdentifierProperty()) + final CDOPropertyGetter getter; + if (mappedProperty == mappedEntity.getIdentifierProperty()) { - return new CDOIDPropertyGetter(this, mappedProperty.getName()); + getter = new CDOIDPropertyGetter(this, mappedProperty.getName()); } else if (mappedProperty.getMetaAttribute("version") != null) { - return new CDOVersionPropertyGetter(this, mappedProperty.getName()); + getter = new CDOVersionPropertyGetter(this, mappedProperty.getName()); } else if (mappedProperty.getName().compareTo(CDOHibernateConstants.RESOURCE_PROPERTY) == 0) { - return new CDOResourceIDGetter(this, mappedProperty.getName()); + getter = new CDOResourceIDGetter(this, mappedProperty.getName()); } else if (mappedProperty.getName().compareTo(CDOHibernateConstants.CONTAINER_PROPERTY) == 0) { - return new CDOContainerGetter(this, mappedProperty.getName()); + getter = new CDOContainerGetter(this, mappedProperty.getName()); } else if (mappedProperty.getName().compareTo(CDOHibernateConstants.COMMITTIMESTAMP_PROPERTY) == 0) { - return new CDOBranchTimeStampGetter(this, mappedProperty.getName()); - } - - EStructuralFeature feature = getEClass().getEStructuralFeature(mappedProperty.getName()); - if (feature instanceof EReference && feature.isMany()) - { - return new CDOManyReferenceGetter(this, mappedProperty.getName()); - } - else if (feature instanceof EReference) - { - return new CDOReferenceGetter(this, mappedProperty.getName()); + getter = new CDOBranchTimeStampGetter(this, mappedProperty.getName()); } - else if (feature instanceof EAttribute && feature.isMany()) + else { - return new CDOManyAttributeGetter(this, mappedProperty.getName()); + + EStructuralFeature feature = getEClass().getEStructuralFeature(mappedProperty.getName()); + if (feature instanceof EReference && feature.isMany()) + { + getter = new CDOManyReferenceGetter(this, mappedProperty.getName()); + } + else if (feature instanceof EReference) + { + getter = new CDOReferenceGetter(this, mappedProperty.getName()); + } + else if (feature instanceof EAttribute && feature.isMany()) + { + getter = new CDOManyAttributeGetter(this, mappedProperty.getName()); + } + else + { + getter = new CDOPropertyGetter(this, mappedProperty.getName()); + } } - return new CDOPropertyGetter(this, mappedProperty.getName()); + HibernateStore hbStore = HibernateStore.getCurrentHibernateStore(); + getter.setPersistenceOptions(hbStore.getCDODataStore().getPersistenceOptions()); + return getter; } @Override @@ -250,52 +260,56 @@ public class CDORevisionTuplizer extends AbstractEntityTuplizer return mappedProperty.getSetter(mappedEntity.getMappedClass()); } + final CDOPropertySetter setter; if (mappedProperty == mappedEntity.getIdentifierProperty()) { setIdentifierTypeAsAnnotation(mappedProperty); - return new CDOIDPropertySetter(this, mappedProperty.getName()); + setter = new CDOIDPropertySetter(this, mappedProperty.getName()); } - - if (mappedProperty.getMetaAttribute("version") != null) + else if (mappedProperty.getMetaAttribute("version") != null) { - return new CDOVersionPropertySetter(this, mappedProperty.getName()); + setter = new CDOVersionPropertySetter(this, mappedProperty.getName()); } + else if (mappedProperty.getName().compareTo(CDOHibernateConstants.RESOURCE_PROPERTY) == 0) { - return new CDOResourceIDSetter(this, mappedProperty.getName()); + setter = new CDOResourceIDSetter(this, mappedProperty.getName()); } - - if (mappedProperty.getName().compareTo(CDOHibernateConstants.CONTAINER_PROPERTY) == 0) - { - return new CDOContainerSetter(this, mappedProperty.getName()); - } - - if (mappedProperty.getName().compareTo(CDOHibernateConstants.COMMITTIMESTAMP_PROPERTY) == 0) + else if (mappedProperty.getName().compareTo(CDOHibernateConstants.CONTAINER_PROPERTY) == 0) { - return new CDOBranchTimeStampSetter(this, mappedProperty.getName()); + setter = new CDOContainerSetter(this, mappedProperty.getName()); } - - EStructuralFeature feature = getEClass().getEStructuralFeature(mappedProperty.getName()); - if (feature instanceof EReference && feature.isMany()) + else if (mappedProperty.getName().compareTo(CDOHibernateConstants.COMMITTIMESTAMP_PROPERTY) == 0) { - // TODO Clarify feature maps - return new CDOManyReferenceSetter(this, mappedProperty.getName()); + setter = new CDOBranchTimeStampSetter(this, mappedProperty.getName()); } - - if (feature instanceof EAttribute && feature.isMany()) + else { - // TODO Clarify feature maps - return new CDOManyAttributeSetter(this, mappedProperty.getName()); - } + EStructuralFeature feature = getEClass().getEStructuralFeature(mappedProperty.getName()); + if (feature instanceof EReference && feature.isMany()) + { + setter = new CDOManyReferenceSetter(this, mappedProperty.getName()); + } + else if (feature instanceof EAttribute && feature.isMany()) + { + setter = new CDOManyAttributeSetter(this, mappedProperty.getName()); + } + else - if (feature instanceof EReference) - { - // TODO Clarify feature maps - return new CDOReferenceSetter(this, mappedProperty.getName()); + if (feature instanceof EReference) + { + setter = new CDOReferenceSetter(this, mappedProperty.getName()); + } + else + { + setter = new CDOPropertySetter(this, mappedProperty.getName()); + } } - return new CDOPropertySetter(this, mappedProperty.getName()); + HibernateStore hbStore = HibernateStore.getCurrentHibernateStore(); + setter.setPersistenceOptions(hbStore.getCDODataStore().getPersistenceOptions()); + return setter; } @Override |