/* * Copyright (c) 2008-2013, 2015, 2016 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 * Martin Taal - moved cdopackage handler to other class, changed configuration */ 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.CDOID.ObjectType; import org.eclipse.emf.cdo.common.model.CDOClassifierRef; import org.eclipse.emf.cdo.common.model.CDOModelUtil; import org.eclipse.emf.cdo.eresource.EresourcePackage; import org.eclipse.emf.cdo.etypes.EtypesPackage; import org.eclipse.emf.cdo.internal.server.TransactionCommitContext.TransactionPackageRegistry; import org.eclipse.emf.cdo.server.ISession; import org.eclipse.emf.cdo.server.ITransaction; import org.eclipse.emf.cdo.server.IView; import org.eclipse.emf.cdo.server.hibernate.IHibernateMappingProvider; 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; import org.eclipse.net4j.db.DBException; import org.eclipse.net4j.util.WrappedException; import org.eclipse.net4j.util.io.IOUtil; import org.eclipse.net4j.util.lifecycle.LifecycleUtil; import org.eclipse.net4j.util.om.log.OMLogger; 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.EPackage; import org.eclipse.emf.teneo.Constants; import org.eclipse.emf.teneo.PackageRegistryProvider; import org.eclipse.emf.teneo.PersistenceOptions; import org.eclipse.emf.teneo.annotations.mapper.PersistenceMappingBuilder; import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedModel; import org.eclipse.emf.teneo.hibernate.EMFInterceptor; 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; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Environment; import org.hibernate.event.service.spi.EventListenerRegistry; import org.hibernate.event.spi.EventType; import org.hibernate.internal.SessionFactoryImpl; import org.hibernate.mapping.PersistentClass; import org.hibernate.service.ServiceRegistry; import org.hibernate.tool.hbm2ddl.SchemaExport; import org.hibernate.type.StandardBasicTypes; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import java.util.Map; import java.util.Properties; import java.util.Set; /** * @author Eike Stepper * @author Martin Taal */ public class HibernateStore extends Store implements IHibernateStore { public static final String PERSISTENCE_XML = PersistenceOptions.PERSISTENCE_XML; public static final String TYPE = "hibernate"; //$NON-NLS-1$ public static final String ID_TYPE_EANNOTATION_SOURCE = "teneo.cdo"; public static final String ID_TYPE_EANNOTATION_KEY = "id_type"; public static final Set<ObjectType> OBJECT_ID_TYPES = new HashSet<ObjectType>( Arrays.asList(CDOID.ObjectType.STRING_WITH_CLASSIFIER, CDOID.ObjectType.LONG_WITH_CLASSIFIER)); private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, HibernateStore.class); private static final String RESOURCE_HBM_PATH = "mappings/resource.hbm.xml"; //$NON-NLS-1$ private static final String HBM2DLL_UPDATE = "update"; //$NON-NLS-1$ private static final String HBM2DLL_CREATE = "create"; //$NON-NLS-1$ /** * Used to give different extensions of Hibernate a context when initializing */ private static ThreadLocal<HibernateStore> currentHibernateStore = new ThreadLocal<HibernateStore>(); private HbSessionDataStore cdoDataStore; private HibernateAuditHandler hibernateAuditHandler; private HibernatePackageHandler packageHandler; private IHibernateMappingProvider mappingProvider; private boolean doDropSchema; private SystemInformation systemInformation; private List<EPackage> auditEPackages; private Map<String, String> identifierPropertyNameByEntity; private Properties properties; // is initialized on get private CDOBranchPoint mainBranchHead; private String mappingXml = null; public HibernateStore(IHibernateMappingProvider mappingProvider) { this(mappingProvider, null); } public HibernateStore(IHibernateMappingProvider mappingProvider, Properties properties) { super(TYPE, OBJECT_ID_TYPES, set(ChangeFormat.REVISION), set(RevisionTemporality.NONE, RevisionTemporality.AUDITING), set(RevisionParallelism.NONE)); this.mappingProvider = mappingProvider; packageHandler = new HibernatePackageHandler(this); this.properties = properties; if (TRACER.isEnabled() && mappingProvider != null) { TRACER.trace("HibernateStore with mappingProvider " + mappingProvider.getClass().getName()); //$NON-NLS-1$ } } public boolean isAuditing() { return getRevisionTemporality() == RevisionTemporality.AUDITING; } public CDOBranchPoint getMainBranchHead() { if (mainBranchHead == null) { mainBranchHead = getRepository().getBranchManager().getMainBranch().getHead(); } return mainBranchHead; } public String getIdentifierPropertyName(String entityName) { return identifierPropertyNameByEntity.get(entityName); } public boolean isMapped(EClass eClass) { return null != cdoDataStore.toEntityName(eClass); } public Properties getProperties() { if (properties == null || properties.isEmpty()) { properties = new Properties(); final Map<String, String> storeProps = getRepository().getProperties(); for (String key : storeProps.keySet()) { properties.setProperty(key, storeProps.get(key)); } } return properties; } public void addEntityNameEClassMapping(String entityName, EClass eClass) { cdoDataStore.addEntityNameEClassMapping(entityName, eClass); } /** * Returns all model epackages, so no audit epackages or system * epackages. */ public List<EPackage> getModelEPackages() { final List<EPackage> epacks = getPackageHandler().getEPackages(); final ListIterator<EPackage> iterator = epacks.listIterator(); while (iterator.hasNext()) { final EPackage epack = iterator.next(); if (CDOModelUtil.isSystemPackage(epack) && epack != EtypesPackage.eINSTANCE) { iterator.remove(); } else if (isAuditEPackage(epack)) { // an auditing package iterator.remove(); } } return epacks; } private boolean isAuditEPackage(EPackage ePackage) { return TeneoauditingPackage.eNS_URI.equals(ePackage.getNsURI()) || ePackage.getEAnnotation(Constants.ANNOTATION_SOURCE_AUDITING) != null; } public String getEntityName(EClass eClass) { if (eClass == null) { throw new IllegalArgumentException("EClass argument is null"); //$NON-NLS-1$ } final String entityName = cdoDataStore.toEntityName(eClass); if (entityName == null) { throw new IllegalArgumentException("EClass " + eClass.getName() //$NON-NLS-1$ + " does not have an entity name, has it been mapped to Hibernate?"); //$NON-NLS-1$ } return entityName; } public String getEntityName(CDOClassifierRef classifierRef) { if (classifierRef == null) { throw new IllegalArgumentException("classifierRef argument is null"); //$NON-NLS-1$ } EClass eClass = (EClass)classifierRef.resolve(getRepository().getPackageRegistry()); // initialize everything getHibernateSessionFactory(); final String entityName = cdoDataStore.toEntityName(eClass); if (entityName == null) { throw new IllegalArgumentException("EClass " + classifierRef //$NON-NLS-1$ + " does not have an entity name, has it been mapped to Hibernate?"); //$NON-NLS-1$ } return entityName; } public EClass getEClass(String entityName) { if (entityName == null) { throw new IllegalArgumentException("entityname argument is null"); //$NON-NLS-1$ } final EClass eClass = cdoDataStore.toEClass(entityName); if (eClass == null) { throw new IllegalArgumentException("entityname " + entityName //$NON-NLS-1$ + " does not map to an EClass, has it been mapped to Hibernate?"); //$NON-NLS-1$ } return eClass; } public Configuration getHibernateConfiguration() { return cdoDataStore.getConfiguration(); } public synchronized SessionFactory getHibernateSessionFactory() { if (cdoDataStore == null) { if (TRACER.isEnabled()) { TRACER.trace("Initializing SessionFactory for HibernateStore"); //$NON-NLS-1$ } currentHibernateStore.set(this); identifierPropertyNameByEntity = new HashMap<String, String>(); try { initDataStore(); // this has to be done before the classmapping is iterated // otherwise it is not initialized SessionFactory hibernateSessionFactory = cdoDataStore.getSessionFactory(); ServiceRegistry serviceRegistry = ((SessionFactoryImpl)hibernateSessionFactory).getServiceRegistry(); final EventListenerRegistry eventListenerRegistry = serviceRegistry.getService(EventListenerRegistry.class); eventListenerRegistry.setListeners(EventType.MERGE, new CDOMergeEventListener()); final Iterator<?> iterator = cdoDataStore.getConfiguration().getClassMappings(); while (iterator.hasNext()) { final PersistentClass pc = (PersistentClass)iterator.next(); if (pc.getIdentifierProperty() == null) { // happens for featuremaps for now... continue; } identifierPropertyNameByEntity.put(pc.getEntityName(), pc.getIdentifierProperty().getName()); } } catch (Throwable t) { t.printStackTrace(System.err); if (TRACER.isEnabled()) { TRACER.trace(t); } throw new RuntimeException(t); } finally { currentHibernateStore.set(null); } } return cdoDataStore.getSessionFactory(); } public void ensureCorrectPackageRegistry() { if (cdoDataStore == null) { return; } if (cdoDataStore.getPackageRegistry() instanceof TransactionPackageRegistry) { setInternalPackageRegistry(); } } private synchronized void setInternalPackageRegistry() { cdoDataStore.setPackageRegistry(getRepository().getPackageRegistry(false)); } public Connection getConnection() { String connectionURL = getProperties().getProperty("hibernate.connection.url"); String userName = getProperties().getProperty("hibernate.connection.username"); String passWord = getProperties().getProperty("hibernate.connection.password"); try { Connection connection = DriverManager.getConnection(connectionURL, userName, passWord); if (connection == null) { throw new DBException("No connection from driver manager: " + connectionURL); //$NON-NLS-1$ } String autoCommit = getProperties().getProperty("hibernate.connection.autocommit"); if (autoCommit != null) { connection.setAutoCommit(Boolean.valueOf(autoCommit)); } return connection; } catch (SQLException ex) { throw new DBException(ex); } } @Deprecated public boolean isLocal(CDOID id) { throw new UnsupportedOperationException(); } public CDOID createObjectID(String val) { final int index = val.lastIndexOf(CDOClassifierRef.URI_SEPARATOR); if (index == -1) { throw new IllegalArgumentException("Id string " + val + " is not a valid id"); } final String uriPart = val.substring(0, index); final String idPart = val.substring(index + 1); final CDOClassifierRef classifierRef = new CDOClassifierRef(uriPart); final String entityName = getEntityName(classifierRef); final EClass eClass = getEClass(entityName); final EAnnotation typeEAnnotation = eClass.getEAnnotation(ID_TYPE_EANNOTATION_SOURCE); if (typeEAnnotation == null) { throw new IllegalStateException("EClass " + eClass + " does not have a type annotation"); } final String idTypeStr = typeEAnnotation.getDetails().get(ID_TYPE_EANNOTATION_KEY); if (StandardBasicTypes.STRING.getName().equals(idTypeStr)) { return HibernateUtil.getInstance().createCDOID(classifierRef, idPart); } else if (StandardBasicTypes.LONG.getName().equals(idTypeStr)) { return HibernateUtil.getInstance().createCDOID(classifierRef, new Long(idPart)); } else { throw new IllegalArgumentException("ID type " + idTypeStr + " not supported "); } } @Override public HibernateStoreAccessor createReader(ISession session) { return new HibernateStoreAccessor(this, session); } @Override public HibernateStoreAccessor createWriter(ITransaction transaction) { return new HibernateStoreAccessor(this, transaction); } public Map<String, String> getPersistentProperties(Set<String> names) { final Map<String, String> result = packageHandler.getSystemProperties(); if (names == null || names.isEmpty()) { return result; } final Map<String, String> filteredResult = new HashMap<String, String>(); for (String name : names) { if (result.containsKey(name)) { filteredResult.put(name, result.get(name)); } } return filteredResult; } public void setPersistentProperties(Map<String, String> properties) { packageHandler.setSystemProperties(properties); } public void removePersistentProperties(Set<String> names) { final Map<String, String> props = getPersistentProperties(null); for (String name : names) { props.remove(name); } setPersistentProperties(props); } public synchronized int getNextPackageID() { return packageHandler.getNextPackageID(); } public synchronized int getNextClassID() { return packageHandler.getNextClassID(); } public synchronized int getNextFeatureID() { return packageHandler.getNextFeatureID(); } public long getCreationTime() { return getSystemInformation().getCreationTime(); } public void setCreationTime(long creationTime) { getSystemInformation().setCreationTime(creationTime); } public HibernatePackageHandler getPackageHandler() { return packageHandler; } // TODO: synchronize?? @Override protected void doActivate() throws Exception { super.doActivate(); packageHandler.activate(); } @Override protected void doDeactivate() throws Exception { Configuration configuration = null; if (cdoDataStore != null) { configuration = cdoDataStore.getConfiguration(); if (TRACER.isEnabled()) { TRACER.trace("Closing SessionFactory"); //$NON-NLS-1$ } cdoDataStore.close(); } // and now do the drop action if (configuration != null && doDropSchema) { final SchemaExport se = new SchemaExport(configuration); se.drop(false, true); } cdoDataStore = null; hibernateAuditHandler = null; // get rid of the audit epackages if (auditEPackages != null) { for (EPackage ePackage : auditEPackages) { getRepository().getPackageRegistry().remove(ePackage.getNsURI()); } auditEPackages = null; } LifecycleUtil.deactivate(packageHandler, OMLogger.Level.WARN); super.doDeactivate(); } @Override protected StoreAccessorPool getReaderPool(ISession session, boolean forReleasing) { // TODO Consider usings multiple pools for readers (e.g. bound to the session context) return null; } @Override protected StoreAccessorPool getWriterPool(IView view, boolean forReleasing) { // TODO Consider usings multiple pools for writers (e.g. bound to the session context) return null; } // is called after a new package has been added // TODO: synchronize?? // TODO: combine with doActivate/doDeactivate?? // TODO: assumes that packageHandler has been reset protected void reInitialize() { if (TRACER.isEnabled()) { TRACER.trace("Re-Initializing HibernateStore"); //$NON-NLS-1$ } if (cdoDataStore != null) { if (!cdoDataStore.isClosed()) { if (TRACER.isEnabled()) { TRACER.trace("Closing SessionFactory"); //$NON-NLS-1$ } cdoDataStore.close(); } cdoDataStore = null; } } protected void initDataStore() { if (TRACER.isEnabled()) { TRACER.trace("Initializing Configuration"); //$NON-NLS-1$ } InputStream in = null; try { PackageRegistryProvider.getInstance().setThreadPackageRegistry(getRepository().getPackageRegistry()); cdoDataStore = new CDODataStore(); hibernateAuditHandler = new HibernateAuditHandler(); hibernateAuditHandler.setCdoDataStore(cdoDataStore); hibernateAuditHandler.setHibernateStore(this); cdoDataStore.setResetConfigurationOnInitialization(false); cdoDataStore.setName("cdo"); cdoDataStore.setPackageRegistry(getRepository().getPackageRegistry()); cdoDataStore.getExtensionManager().registerExtension(EMFInterceptor.class.getName(), CDOInterceptor.class.getName()); cdoDataStore.getExtensionManager().registerExtension(AuditHandler.class.getName(), CDOAuditHandler.class.getName()); cdoDataStore.getExtensionManager().registerExtension(AuditProcessHandler.class.getName(), CDOAuditProcessHandler.class.getName()); // don't do any persistence xml mapping in this datastore // make a local copy as it is adapted in the next if-statement // and we want to keep the original one untouched, if not // subsequent test runs will fail as they use the same // properties object 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(); if (mappingProvider != null) { mappingProvider.setHibernateStore(this); mappingXml = mappingProvider.getMapping(); hibernateConfiguration.addXML(mappingXml); } if (TRACER.isEnabled()) { TRACER.trace("Adding resource.hbm.xml to configuration"); //$NON-NLS-1$ } in = OM.BUNDLE.getInputStream(RESOURCE_HBM_PATH); hibernateConfiguration.addInputStream(in); // hibernateConfiguration.setInterceptor(new CDOInterceptor()); hibernateConfiguration.setProperties(props); // prevent the drop on close because the sessionfactory is also closed when // new packages are written to the db, so only do a real drop at deactivate if (hibernateConfiguration.getProperty(Environment.HBM2DDL_AUTO) != null && hibernateConfiguration.getProperty(Environment.HBM2DDL_AUTO).startsWith(HBM2DLL_CREATE)) { doDropSchema = true; // note that the value create also re-creates the db and drops the old one hibernateConfiguration.setProperty(Environment.HBM2DDL_AUTO, HBM2DLL_UPDATE); cdoDataStore.getDataStoreProperties().setProperty(Environment.HBM2DDL_AUTO, HBM2DLL_UPDATE); } else { doDropSchema = false; } final List<EPackage> ePackages = new ArrayList<EPackage>(packageHandler.getEPackages()); // get rid of the system packages for (EPackage ePackage : packageHandler.getEPackages()) { if (CDOModelUtil.isSystemPackage(ePackage) && ePackage != EtypesPackage.eINSTANCE) { ePackages.remove(ePackage); } } // remove the persistence xml if no epackages as this won't work without // epackages if (ePackages.size() == 0 && props.getProperty(PersistenceOptions.PERSISTENCE_XML) != null) { cdoDataStore.getDataStoreProperties().remove(PersistenceOptions.PERSISTENCE_XML); } if (isAuditing()) { auditEPackages = createAuditEPackages(cdoDataStore); final String auditMapping = mapAuditingEPackages(cdoDataStore, auditEPackages); // System.err.println(auditMapping); hibernateConfiguration.addXML(auditMapping); cdoDataStore.setAuditing(true); } cdoDataStore.setEPackages(ePackages.toArray(new EPackage[0])); } catch (Exception ex) { throw WrappedException.wrap(ex); } finally { PackageRegistryProvider.getInstance().setThreadPackageRegistry(null); IOUtil.close(in); } } public static HibernateStore getCurrentHibernateStore() { return currentHibernateStore.get(); } public boolean isFirstStart() { return getSystemInformation().isFirstTime(); } private SystemInformation getSystemInformation() { if (systemInformation == null) { systemInformation = getPackageHandler().getSystemInformation(); } return systemInformation; } public String getMappingXml() { return mappingXml; } private List<EPackage> createAuditEPackages(HbDataStore dataStore) { final PersistenceOptions po = dataStore.getPersistenceOptions(); final List<EPackage> epacks = new ArrayList<EPackage>(); for (EPackage ePackage : getModelEPackages()) { if (!CDOModelUtil.isSystemPackage(ePackage) && !isAuditEPackage(ePackage)) { epacks.add(dataStore.getAuditHandler().createAuditingEPackage(dataStore, ePackage, getRepository().getPackageRegistry(), po)); } } epacks.add(dataStore.getAuditHandler().createAuditingEPackage(dataStore, getRepository().getPackageRegistry().getEPackage(EresourcePackage.eNS_URI), getRepository().getPackageRegistry(), po)); epacks.add(TeneoauditingPackage.eINSTANCE); getRepository().getPackageRegistry().put(TeneoauditingPackage.eNS_URI, TeneoauditingPackage.eINSTANCE); // also register them all in the non-transaction registry for (EPackage ePackage : epacks) { getRepository().getPackageRegistry(false).put(ePackage.getNsURI(), ePackage); } return epacks; } public String mapAuditingEPackages(HbDataStore dataStore, List<EPackage> auditEPackages) { // create a new persistence options to not change the original final Properties props = new Properties(); props.putAll(dataStore.getPersistenceOptions().getProperties()); props.remove(PersistenceOptions.PERSISTENCE_XML); if (props.containsKey(PersistenceOptions.AUDITING_PERSISTENCE_XML)) { props.setProperty(PersistenceOptions.PERSISTENCE_XML, PersistenceOptions.AUDITING_PERSISTENCE_XML); } final PersistenceOptions po = dataStore.getExtensionManager().getExtension(PersistenceOptions.class, new Object[] { props }); PAnnotatedModel paModel = dataStore.getExtensionManager().getExtension(PersistenceMappingBuilder.class).buildMapping(auditEPackages, po, dataStore.getExtensionManager(), dataStore.getPackageRegistry()); final HibernateMappingGenerator hmg = dataStore.getExtensionManager().getExtension(HibernateMappingGenerator.class); hmg.setPersistenceOptions(po); final String hbm = hmg.generateToString(paModel); return hbm; } private class CDODataStore extends HbSessionDataStore { private static final long serialVersionUID = 1L; @Override protected void addContainerMapping(PersistentClass pc) { // prevent container mapping for cdo objects if (pc.getTuplizerMap() != null) { for (Object tuplizerName : pc.getTuplizerMap().values()) { if (((String)tuplizerName).contains("org.eclipse.emf.cdo")) { return; } } } super.addContainerMapping(pc); } @Override protected void mapModel() { if (getPersistenceOptions().getMappingFilePath() != null || getPersistenceOptions().isUseMappingFile()) { super.mapModel(); } } } public HibernateAuditHandler getHibernateAuditHandler() { ensureCorrectPackageRegistry(); return hibernateAuditHandler; } public void setHibernateAuditHandler(HibernateAuditHandler hibernateAuditHandler) { this.hibernateAuditHandler = hibernateAuditHandler; } public static class CDOAuditProcessHandler extends AuditProcessHandler { private static final long serialVersionUID = 1L; @Override protected long getCommitTime() { if (HibernateThreadContext.isCommitContextSet()) { return HibernateThreadContext.getCommitContext().getCommitContext().getBranchPoint().getTimeStamp(); } return super.getCommitTime(); } @Override protected void doAuditWorkInSession(Session session, List<AuditWork> auditWorks) { try { PackageRegistryProvider.getInstance().setThreadPackageRegistry(getDataStore().getPackageRegistry()); if (HibernateThreadContext.isCommitContextSet()) { AuditProcessHandler.setCurrentUserName(HibernateThreadContext.getCommitContext().getCommitContext().getUserID()); AuditProcessHandler.setCurrentComment(HibernateThreadContext.getCommitContext().getCommitContext().getCommitComment()); } super.doAuditWorkInSession(session, auditWorks); } finally { PackageRegistryProvider.getInstance().setThreadPackageRegistry(null); AuditProcessHandler.setCurrentUserName(null); 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()); } @Override protected boolean performVersionCheck() { return true; } } public HbSessionDataStore getCDODataStore() { return cdoDataStore; } }