You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2015/09/10 14:07:01 UTC

[02/50] [abbrv] isis git commit: ISIS-1194: moving persistence classes around, removing PersistenceSessionFactoryAware. ; + fix for unit test per previous commit

ISIS-1194: moving persistence classes around, removing PersistenceSessionFactoryAware. ; + fix for unit test per previous commit

moved:
-DataNucleusApplicationComponents
- FrameworkSynchronizer
- IsisLifecycleListener (renamed as ...2 to ensure backward compatibility)

also:
- CreateSchemaObjectFromClassMetadata no longer requires PersistenceSessionFactory so remove PersistenceSessionFactoryAware interface
- fixing test that references ObjectStore#name() - was removed in previous commit.


Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/d369891c
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/d369891c
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/d369891c

Branch: refs/heads/ISIS-1194
Commit: d369891c3a20ebfbf7837ff6da7609597176fdbf
Parents: 155b1b6
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Wed Sep 9 17:32:27 2015 +0100
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Wed Sep 9 17:32:27 2015 +0100

----------------------------------------------------------------------
 ..._ug_more-advanced_decoupling_db-schemas.adoc |  14 +-
 .../DataNucleusApplicationComponents.java       | 298 +++++++++++++
 .../persistence/FrameworkSynchronizer.java      | 413 ++++++++++++++++++
 .../persistence/IsisLifecycleListener2.java     | 281 +++++++++++++
 .../system/persistence/LoggingLocation.java     |  27 ++
 .../runtime/system/persistence/ObjectStore.java |   4 +-
 .../system/persistence/PersistenceSession.java  |   1 -
 .../persistence/PersistenceSessionFactory.java  |   1 -
 .../system/persistence/SuspendableListener.java |  27 ++
 .../core/runtime/system/persistence/Utils.java  |  50 +++
 .../CreateSchemaObjectFromClassMetadata.java    |  12 +-
 .../DataNucleusApplicationComponents.java       | 297 -------------
 ...ataNucleusPersistenceMechanismInstaller.java |   3 -
 .../PersistenceManagerFactoryAware.java         |  26 --
 .../persistence/FrameworkSynchronizer.java      | 416 -------------------
 .../persistence/IsisLifecycleListener.java      | 266 +-----------
 .../persistence/LoggingLocation.java            |  27 --
 .../persistence/SuspendableListener.java        |  27 --
 .../jdo/datanucleus/persistence/Utils.java      |  51 ---
 ...rsistenceQueryFindAllInstancesProcessor.java |   2 +-
 ...tenceQueryFindUsingApplibQueryProcessor.java |   2 +-
 .../PersistenceQueryProcessorAbstract.java      |   4 +-
 .../persistence/PersistenceSessionTest.java     |   1 -
 23 files changed, 1114 insertions(+), 1136 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/d369891c/adocs/documentation/src/main/asciidoc/guides/_ug_more-advanced_decoupling_db-schemas.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ug_more-advanced_decoupling_db-schemas.adoc b/adocs/documentation/src/main/asciidoc/guides/_ug_more-advanced_decoupling_db-schemas.adoc
index 7cdbbb1..e918ae7 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_ug_more-advanced_decoupling_db-schemas.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_ug_more-advanced_decoupling_db-schemas.adoc
@@ -73,7 +73,6 @@ The guts of its implementation is:
 ----
 public class CreateSchemaObjectFromClassMetadata
         implements MetaDataListener,
-                   PersistenceManagerFactoryAware,
                    DataNucleusPropertiesAware {
     @Override
     public void loaded(final AbstractClassMetaData cmd) { ... }
@@ -123,16 +122,7 @@ Because this pertains to the JDO Objectstore we suggest you put this configurati
 
 Any implementation must implement `org.datanucleus.metadata.MetaDataListener`.  In many cases simply subclassing from `CreateSchemaObjectFromClassMetadata` and overriding `buildSqlToCheck(...)` and `buildSqlToExec(...)` should suffice.
 
-If you _do_ need more control, your implementation can also optionally implement `org.apache.isis.objectstore.jdo.datanucleus.PersistenceManagerFactoryAware`:
-
-[source,java]
-----
-public interface PersistenceManagerFactoryAware {
-    public void setPersistenceManagerFactory(final PersistenceManagerFactory persistenceManagerFactory);
-}
-----
-
-and also `org.apache.isis.objectstore.jdo.datanucleus.DataNucleusPropertiesAware`:
+If you _do_ need more control, your implementation can also optionally implement  `org.apache.isis.objectstore.jdo.datanucleus.DataNucleusPropertiesAware`:
 
 [source,java]
 ----
@@ -141,7 +131,7 @@ public interface DataNucleusPropertiesAware {
 }
 ----
 
-This latter interface provides access to the properties passed through to JDO/DataNucleus.
+This provides access to the properties passed through to JDO/DataNucleus.
 
 
 [IMPORTANT]

http://git-wip-us.apache.org/repos/asf/isis/blob/d369891c/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/DataNucleusApplicationComponents.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/DataNucleusApplicationComponents.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/DataNucleusApplicationComponents.java
new file mode 100644
index 0000000..95e5c8c
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/DataNucleusApplicationComponents.java
@@ -0,0 +1,298 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.core.runtime.system.persistence;
+
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.jdo.JDOHelper;
+import javax.jdo.PersistenceManager;
+import javax.jdo.PersistenceManagerFactory;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.Maps;
+
+import org.datanucleus.PersistenceNucleusContext;
+import org.datanucleus.PropertyNames;
+import org.datanucleus.api.jdo.JDOPersistenceManagerFactory;
+import org.datanucleus.metadata.MetaDataListener;
+import org.datanucleus.metadata.MetaDataManager;
+import org.datanucleus.store.StoreManager;
+import org.datanucleus.store.schema.SchemaAwareStoreManager;
+
+import org.apache.isis.core.commons.components.ApplicationScopedComponent;
+import org.apache.isis.core.commons.config.IsisConfiguration;
+import org.apache.isis.core.commons.factory.InstanceUtil;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.objectstore.jdo.datanucleus.CreateSchemaObjectFromClassMetadata;
+import org.apache.isis.objectstore.jdo.datanucleus.DataNucleusPropertiesAware;
+import org.apache.isis.objectstore.jdo.datanucleus.persistence.IsisLifecycleListener;
+import org.apache.isis.objectstore.jdo.metamodel.facets.object.query.JdoNamedQuery;
+import org.apache.isis.objectstore.jdo.metamodel.facets.object.query.JdoQueryFacet;
+
+public class DataNucleusApplicationComponents implements ApplicationScopedComponent {
+
+    public static final String CLASS_METADATA_LOADED_LISTENER_KEY = "classMetadataLoadedListener";
+    static final String CLASS_METADATA_LOADED_LISTENER_DEFAULT = CreateSchemaObjectFromClassMetadata.class.getName();
+
+    ///////////////////////////////////////////////////////////////////////////
+    // JRebel support
+    ///////////////////////////////////////////////////////////////////////////
+
+    private static DataNucleusApplicationComponents instance;
+    
+    /**
+     * For JRebel plugin
+     */
+    public static MetaDataManager getMetaDataManager() {
+        return instance != null
+                ? ((JDOPersistenceManagerFactory)instance.persistenceManagerFactory).getNucleusContext().getMetaDataManager() 
+                : null;
+    }
+
+    public static void markAsStale() {
+        if(instance != null) {
+            instance.stale = true;
+        }
+    }
+
+    private boolean stale = false;
+    public boolean isStale() {
+        return stale;
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+
+    private final Set<String> persistableClassNameSet;
+    private final IsisConfiguration jdoObjectstoreConfig;
+    private final Map<String, String> datanucleusProps;
+    
+    private final IsisLifecycleListener lifecycleListener;
+    private final FrameworkSynchronizer synchronizer;
+    
+    private Map<String, JdoNamedQuery> namedQueryByName;
+    private PersistenceManagerFactory persistenceManagerFactory;
+
+    public DataNucleusApplicationComponents(
+            final IsisConfiguration jdoObjectstoreConfig,
+            final Map<String, String> datanucleusProps,
+            final Set<String> persistableClassNameSet) {
+    
+        this.datanucleusProps = datanucleusProps;
+        this.persistableClassNameSet = persistableClassNameSet;
+        this.jdoObjectstoreConfig = jdoObjectstoreConfig;
+
+        this.synchronizer = new FrameworkSynchronizer();
+        this.lifecycleListener = new IsisLifecycleListener(synchronizer);
+
+        initialize();
+        
+        // for JRebel plugin
+        instance = this;
+    }
+
+    private void initialize() {
+        persistenceManagerFactory = createPmfAndSchemaIfRequired(persistableClassNameSet, datanucleusProps);
+
+        namedQueryByName = catalogNamedQueries(persistableClassNameSet);
+    }
+
+    private static boolean isSchemaAwareStoreManager(Map<String,String> datanucleusProps) {
+
+        // we create a throw-away instance of PMF so that we can probe whether DN has
+        // been configured with a schema-aware store manager or not.
+        final JDOPersistenceManagerFactory probePmf =
+                (JDOPersistenceManagerFactory)JDOHelper.getPersistenceManagerFactory(datanucleusProps);
+        try {
+            final PersistenceNucleusContext nucleusContext = probePmf.getNucleusContext();
+            final StoreManager storeManager = nucleusContext.getStoreManager();
+            return storeManager instanceof SchemaAwareStoreManager;
+        } finally {
+            probePmf.close();
+        }
+    }
+
+    // REF: http://www.datanucleus.org/products/datanucleus/jdo/schema.html
+    private PersistenceManagerFactory createPmfAndSchemaIfRequired(final Set<String> persistableClassNameSet, final Map<String, String> datanucleusProps) {
+
+        PersistenceManagerFactory persistenceManagerFactory;
+        if(isSchemaAwareStoreManager(datanucleusProps)) {
+
+            // rather than reinvent too much of the wheel, we reuse the same property that DN would check
+            // for if it were doing the auto-creation itself (read from isis.properties)
+            final boolean createSchema = isSet(datanucleusProps, PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_ALL);
+
+            if(createSchema) {
+
+                // we *don't* use DN's eager loading (autoStart), because doing so means that it attempts to
+                // create the table before the schema (for any entities annotated @PersistenceCapable(schema=...)
+                //
+                // instead, we manually create the schema ourselves
+                // (if the configured StoreMgr supports it, and if requested in isis.properties)
+                //
+                datanucleusProps.put(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_ALL, "false"); // turn off, cos want to do the schema object ourselves...
+                datanucleusProps.put(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_SCHEMA, "false");
+                datanucleusProps.put(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_TABLES, "true"); // but have DN do everything else...
+                datanucleusProps.put(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_COLUMNS, "true");
+                datanucleusProps.put(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_CONSTRAINTS, "true");
+
+                persistenceManagerFactory = JDOHelper.getPersistenceManagerFactory(datanucleusProps);
+                createSchema(persistenceManagerFactory, persistableClassNameSet, datanucleusProps);
+
+            } else {
+                persistenceManagerFactory = JDOHelper.getPersistenceManagerFactory(datanucleusProps);
+            }
+
+        } else {
+
+            // we *DO* use DN's eager loading (autoStart), because it seems that DN requires this (for neo4j at least)
+            // otherwise NPEs occur later.
+
+            configureAutoStart(persistableClassNameSet, datanucleusProps);
+            persistenceManagerFactory = JDOHelper.getPersistenceManagerFactory(this.datanucleusProps);
+        }
+
+        return persistenceManagerFactory;
+
+    }
+
+    private void configureAutoStart(final Set<String> persistableClassNameSet, final Map<String, String> datanucleusProps) {
+        final String persistableClassNames = Joiner.on(',').join(persistableClassNameSet);
+
+        // ref: http://www.datanucleus.org/products/datanucleus/jdo/autostart.html
+        datanucleusProps.put(PropertyNames.PROPERTY_AUTOSTART_MECHANISM, "Classes");
+        datanucleusProps.put(PropertyNames.PROPERTY_AUTOSTART_MODE, "Checked");
+        datanucleusProps.put(PropertyNames.PROPERTY_AUTOSTART_CLASSNAMES, persistableClassNames);
+    }
+
+    private void createSchema(
+            final PersistenceManagerFactory persistenceManagerFactory,
+            final Set<String> persistableClassNameSet,
+            final Map<String, String> datanucleusProps) {
+
+        JDOPersistenceManagerFactory jdopmf = (JDOPersistenceManagerFactory) persistenceManagerFactory;
+        final PersistenceNucleusContext nucleusContext = jdopmf.getNucleusContext();
+        final SchemaAwareStoreManager schemaAwareStoreManager = (SchemaAwareStoreManager)nucleusContext.getStoreManager();
+
+        final MetaDataManager metaDataManager = nucleusContext.getMetaDataManager();
+
+        registerMetadataListener(metaDataManager, datanucleusProps);
+
+        schemaAwareStoreManager.createSchemaForClasses(persistableClassNameSet, asProperties(datanucleusProps));
+    }
+
+    private boolean isSet(final Map<String, String> props, final String key) {
+        return Boolean.parseBoolean( props.get(key) );
+    }
+
+    private void registerMetadataListener(
+            final MetaDataManager metaDataManager,
+            final Map<String, String> datanucleusProps) {
+        final MetaDataListener listener = createMetaDataListener();
+        if(listener == null) {
+            return;
+        }
+
+        if(listener instanceof DataNucleusPropertiesAware) {
+            ((DataNucleusPropertiesAware) listener).setDataNucleusProperties(datanucleusProps);
+        }
+
+
+        // and install the listener for any classes that are lazily loaded subsequently
+        // (shouldn't be any, this is mostly backwards compatibility with previous design).
+        metaDataManager.registerListener(listener);
+    }
+
+    private MetaDataListener createMetaDataListener() {
+        final String classMetadataListenerClassName = jdoObjectstoreConfig.getString(
+                CLASS_METADATA_LOADED_LISTENER_KEY,
+                CLASS_METADATA_LOADED_LISTENER_DEFAULT);
+        return classMetadataListenerClassName != null
+                ? InstanceUtil.createInstance(classMetadataListenerClassName, MetaDataListener.class)
+                : null;
+    }
+
+
+    private static Properties asProperties(final Map<String, String> props) {
+        final Properties properties = new Properties();
+        properties.putAll(props);
+        return properties;
+    }
+
+    private static Map<String, JdoNamedQuery> catalogNamedQueries(Set<String> persistableClassNames) {
+        final Map<String, JdoNamedQuery> namedQueryByName = Maps.newHashMap();
+        for (final String persistableClassName: persistableClassNames) {
+            final ObjectSpecification spec = IsisContext.getSpecificationLoader().loadSpecification(persistableClassName);
+            final JdoQueryFacet facet = spec.getFacet(JdoQueryFacet.class);
+            if (facet == null) {
+                continue;
+            }
+            for (final JdoNamedQuery namedQuery : facet.getNamedQueries()) {
+                namedQueryByName.put(namedQuery.getName(), namedQuery);
+            }
+        }
+        return namedQueryByName;
+    }
+    
+    public PersistenceManagerFactory getPersistenceManagerFactory() {
+        return persistenceManagerFactory;
+    }
+
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    ///////////////////////////////////////////////////////////////////////////
+
+    @Override
+    public void init() {
+    }
+
+    @Override
+    public void shutdown() {
+    }
+
+
+    ///////////////////////////////////////////////////////////////////////////
+    // FrameworkSynchronizer
+    ///////////////////////////////////////////////////////////////////////////
+
+    public FrameworkSynchronizer getFrameworkSynchronizer() {
+        return synchronizer;
+    }
+
+
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    
+    public PersistenceManager createPersistenceManager() {
+        PersistenceManager persistenceManager = persistenceManagerFactory.getPersistenceManager();
+        
+        persistenceManager.addInstanceLifecycleListener(lifecycleListener, (Class[])null);
+        return persistenceManager;
+    }
+
+    public JdoNamedQuery getNamedQuery(String queryName) {
+        return namedQueryByName.get(queryName);
+    }
+
+    
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/d369891c/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/FrameworkSynchronizer.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/FrameworkSynchronizer.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/FrameworkSynchronizer.java
new file mode 100644
index 0000000..1d11948
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/FrameworkSynchronizer.java
@@ -0,0 +1,413 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.core.runtime.system.persistence;
+
+import java.text.MessageFormat;
+import java.util.concurrent.Callable;
+
+import javax.jdo.JDOHelper;
+import javax.jdo.PersistenceManager;
+
+import org.datanucleus.enhancement.Persistable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.isis.core.commons.authentication.AuthenticationSession;
+import org.apache.isis.core.commons.exceptions.IsisException;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager.ConcurrencyChecking;
+import org.apache.isis.core.metamodel.adapter.oid.Oid;
+import org.apache.isis.core.metamodel.adapter.oid.RootOid;
+import org.apache.isis.core.metamodel.adapter.version.ConcurrencyException;
+import org.apache.isis.core.metamodel.adapter.version.Version;
+import org.apache.isis.core.metamodel.facets.object.callbacks.CallbackFacet;
+import org.apache.isis.core.metamodel.facets.object.callbacks.LoadedCallbackFacet;
+import org.apache.isis.core.metamodel.facets.object.callbacks.PersistedCallbackFacet;
+import org.apache.isis.core.metamodel.facets.object.callbacks.PersistingCallbackFacet;
+import org.apache.isis.core.metamodel.facets.object.callbacks.RemovingCallbackFacet;
+import org.apache.isis.core.metamodel.facets.object.callbacks.UpdatedCallbackFacet;
+import org.apache.isis.core.metamodel.facets.object.callbacks.UpdatingCallbackFacet;
+import org.apache.isis.core.runtime.persistence.adaptermanager.AdapterManagerDefault;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.core.runtime.system.transaction.IsisTransaction;
+
+public class FrameworkSynchronizer {
+
+    private static final Logger LOG = LoggerFactory.getLogger(FrameworkSynchronizer.class);
+
+    /**
+     * Categorises where called from.
+     * 
+     * <p>
+     * Just used for logging.
+     */
+    public enum CalledFrom {
+        EVENT_LOAD,
+        EVENT_PRESTORE,
+        EVENT_POSTSTORE,
+        EVENT_PREDIRTY,
+        EVENT_POSTDIRTY,
+        OS_QUERY,
+        OS_RESOLVE,
+        OS_LAZILYLOADED,
+        EVENT_PREDELETE,
+        EVENT_POSTDELETE
+    }
+
+
+    public void postLoadProcessingFor(final Persistable pojo, CalledFrom calledFrom) {
+
+        withLogging(pojo, new Runnable() {
+            @Override
+            public void run() {
+                final Persistable pc = pojo;
+                
+                // need to do eagerly, because (if a viewModel then) a
+                // viewModel's #viewModelMemento might need to use services 
+                getPersistenceSession().getServicesInjector().injectServicesInto(pojo);
+                
+                final Version datastoreVersion = getVersionIfAny(pc);
+                
+                final RootOid originalOid ;
+                ObjectAdapter adapter = getAdapterManager().getAdapterFor(pojo);
+                if(adapter != null) {
+                    ensureRootObject(pojo);
+                    originalOid = (RootOid) adapter.getOid();
+
+                    final Version originalVersion = adapter.getVersion();
+
+                    // sync the pojo held by the adapter with that just loaded
+                    getPersistenceSession().getAdapterManager() .remapRecreatedPojo(adapter, pojo);
+                    
+                    // since there was already an adapter, do concurrency check
+                    // (but don't set abort cause if checking is suppressed through thread-local)
+                    final RootOid thisOid = originalOid;
+                    final Version thisVersion = originalVersion;
+                    final Version otherVersion = datastoreVersion;
+                    
+                    if(thisVersion != null && 
+                       otherVersion != null && 
+                       thisVersion.different(otherVersion)) {
+
+                        if(ConcurrencyChecking.isCurrentlyEnabled()) {
+                            LOG.info("concurrency conflict detected on " + thisOid + " (" + otherVersion + ")");
+                            final String currentUser = getAuthenticationSession().getUserName();
+                            final ConcurrencyException abortCause = new ConcurrencyException(currentUser, thisOid, thisVersion, otherVersion);
+                            getCurrentTransaction().setAbortCause(abortCause);
+
+                        } else {
+                            LOG.warn("concurrency conflict detected but suppressed, on " + thisOid + " (" + otherVersion + ")");
+                        }
+                    }
+                } else {
+                    final OidGenerator oidGenerator = getOidGenerator();
+                    originalOid = oidGenerator.createPersistentOrViewModelOid(pojo);
+                    
+                    // it appears to be possible that there is already an adapter for this Oid, 
+                    // ie from ObjectStore#resolveImmediately()
+                    adapter = getAdapterManager().getAdapterFor(originalOid);
+                    if(adapter != null) {
+                        getPersistenceSession().getAdapterManager() .remapRecreatedPojo(adapter, pojo);
+                    } else {
+                        adapter = getPersistenceSession().getAdapterManager().mapRecreatedPojo(originalOid, pojo);
+                        CallbackFacet.Util.callCallback(adapter, LoadedCallbackFacet.class);
+                    }
+                }
+
+                adapter.setVersion(datastoreVersion);
+            }
+        }, calledFrom);
+    }
+
+
+    /**
+     * Called either when an entity is initially persisted, or when an entity is updated; fires the appropriate
+     * lifecycle callback.
+     *
+     * <p>
+     * The implementation therefore uses Isis' {@link org.apache.isis.core.metamodel.adapter.oid.Oid#isTransient() oid}
+     * to determine which callback to fire.
+     */
+    public void preStoreProcessingFor(final Persistable pojo, final CalledFrom calledFrom) {
+        withLogging(pojo, new Runnable() {
+            @Override
+            public void run() {
+                final ObjectAdapter adapter = getAdapterManager().getAdapterFor(pojo);
+                if(adapter == null) {
+                    // not expected.
+                    return;
+                }
+
+                final RootOid isisOid = (RootOid) adapter.getOid();
+                if (isisOid.isTransient()) {
+                    // persisting
+                    // previously this was performed in the DataNucleusSimplePersistAlgorithm.
+                    CallbackFacet.Util.callCallback(adapter, PersistingCallbackFacet.class);
+                } else {
+                    // updating
+
+                    // don't call here, already called in preDirty.
+
+                    // CallbackFacet.Util.callCallback(adapter, UpdatingCallbackFacet.class);
+                }
+
+            }
+        }, calledFrom);
+    }
+
+    /**
+     * Called either when an entity is initially persisted, or when an entity is updated; fires the appropriate lifecycle callback
+     *
+     * <p>
+     * The implementation therefore uses Isis' {@link org.apache.isis.core.metamodel.adapter.oid.Oid#isTransient() oid}
+     * to determine which callback to fire.
+     */
+    public void postStoreProcessingFor(final Persistable pojo, CalledFrom calledFrom) {
+        withLogging(pojo, new Runnable() {
+            @Override
+            public void run() {
+                ensureRootObject(pojo);
+
+                // assert is persistent
+                if(!pojo.dnIsPersistent()) {
+                    throw new IllegalStateException("Pojo JDO state is not persistent! pojo dnOid: " + JDOHelper.getObjectId(pojo));
+                }
+
+                final ObjectAdapter adapter = getAdapterManager().getAdapterFor(pojo);
+                final RootOid isisOid = (RootOid) adapter.getOid();
+
+
+                if (isisOid.isTransient()) {
+                    // persisting
+                    final RootOid persistentOid = getOidGenerator().createPersistentOrViewModelOid(pojo);
+
+                    getPersistenceSession().getAdapterManager().remapAsPersistent(adapter, persistentOid);
+
+                    CallbackFacet.Util.callCallback(adapter, PersistedCallbackFacet.class);
+
+                    final IsisTransaction transaction = getCurrentTransaction();
+                    transaction.enlistCreated(adapter);
+                } else {
+                    // updating;
+                    // the callback and transaction.enlist are done in the preDirty callback
+                    // (can't be done here, as the enlist requires to capture the 'before' values)
+                    CallbackFacet.Util.callCallback(adapter, UpdatedCallbackFacet.class);
+                }
+
+                Version versionIfAny = getVersionIfAny(pojo);
+                adapter.setVersion(versionIfAny);
+            }
+        }, calledFrom);
+    }
+
+    public void preDirtyProcessingFor(final Persistable pojo, CalledFrom calledFrom) {
+        withLogging(pojo, new Runnable() {
+            @Override
+            public void run() {
+                ObjectAdapter adapter = getAdapterManager().getAdapterFor(pojo);
+                if (adapter == null) {
+                    // seen this happen in the case when a parent entity (LeaseItem) has a collection of children
+                    // objects (LeaseTerm) for which we haven't had a loaded callback fired and so are not yet
+                    // mapped.
+                    
+                    // it seems reasonable in this case to simply map into Isis here ("just-in-time"); presumably
+                    // DN would not be calling this callback if the pojo was not persistent.
+                    
+                    adapter = lazilyLoaded(pojo, CalledFrom.EVENT_PREDIRTY);
+                    if(adapter == null) {
+                        throw new RuntimeException("DN could not find objectId for pojo (unexpected) and so could not map into Isis; pojo=[" +  pojo + "]");
+                    }
+                }
+                if(adapter.isTransient()) {
+                    // seen this happen in the case when there's a 1<->m bidirectional collection, and we're
+                    // attaching the child object, which is being persisted by DN as a result of persistence-by-reachability,
+                    // and it "helpfully" sets up the parent attribute on the child, causing this callback to fire.
+                    // 
+                    // however, at the same time, Isis has only queued up a CreateObjectCommand for the transient object, but it
+                    // hasn't yet executed, so thinks that the adapter is still transient. 
+                    return;
+                }
+
+                CallbackFacet.Util.callCallback(adapter, UpdatingCallbackFacet.class);
+
+                final IsisTransaction transaction = getCurrentTransaction();
+                transaction.enlistUpdating(adapter);
+
+                ensureRootObject(pojo);
+            }
+        }, calledFrom);
+    }
+
+
+    public ObjectAdapter lazilyLoaded(final Persistable pojo, CalledFrom calledFrom) {
+        return withLogging(pojo, new Callable<ObjectAdapter>() {
+            @Override
+            public ObjectAdapter call() {
+                if(getJdoPersistenceManager().getObjectId(pojo) == null) {
+                    return null;
+                }
+                final RootOid oid = getPersistenceSession().getOidGenerator().createPersistentOrViewModelOid(pojo);
+                final ObjectAdapter adapter = getPersistenceSession().getAdapterManager().mapRecreatedPojo(oid, pojo);
+                return adapter;
+            }
+        }, calledFrom);
+    }
+
+    
+    public void preDeleteProcessingFor(final Persistable pojo, final CalledFrom calledFrom) {
+        withLogging(pojo, new Runnable() {
+            @Override
+            public void run() {
+                ObjectAdapter adapter = getAdapterManager().adapterFor(pojo);
+                
+                final IsisTransaction transaction = getCurrentTransaction();
+                transaction.enlistDeleting(adapter);
+
+                CallbackFacet.Util.callCallback(adapter, RemovingCallbackFacet.class);
+            }
+        }, calledFrom);
+        
+    }
+
+    public void postDeleteProcessingFor(final Persistable pojo, final CalledFrom calledFrom) {
+        withLogging(pojo, new Runnable() {
+            @Override
+            public void run() {
+                ObjectAdapter adapter = getAdapterManager().getAdapterFor(pojo);
+                if(adapter == null) {
+                    return;
+                }
+
+                // previously we called the removed callback (if any).
+                // however, this is almost certainly incorrect, because DN will not allow us
+                // to "touch" the pojo once deleted.
+                //
+                // CallbackFacet.Util.callCallback(adapter, RemovedCallbackFacet.class);
+
+
+            }
+        }, calledFrom);
+        
+    }
+    
+    // /////////////////////////////////////////////////////////
+    // Helpers
+    // /////////////////////////////////////////////////////////
+    
+    private <T> T withLogging(Persistable pojo, Callable<T> runnable, CalledFrom calledFrom) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug(logString(calledFrom, LoggingLocation.ENTRY, pojo));
+        }
+        try {
+            return runnable.call();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        } finally {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug(logString(calledFrom, LoggingLocation.EXIT, pojo));
+            }
+        }
+    }
+    
+    private void withLogging(Persistable pojo, final Runnable runnable, CalledFrom calledFrom) {
+        withLogging(pojo, new Callable<Void>() {
+
+            @Override
+            public Void call() throws Exception {
+                runnable.run();
+                return null;
+            }
+            
+        }, calledFrom);
+    }
+    
+    private String logString(CalledFrom calledFrom, LoggingLocation location, Persistable pojo) {
+        final AdapterManager adapterManager = getAdapterManager();
+        final ObjectAdapter adapter = adapterManager.getAdapterFor(pojo);
+        // initial spaces just to look better in log when wrapped by IsisLifecycleListener...
+        return calledFrom.name() + " " + location.prefix + " oid=" + (adapter !=null? adapter.getOid(): "(null)") + " ,pojo " + pojo;
+    }
+
+
+    // /////////////////////////////////////////////////////////
+    // More Helpers...
+    // /////////////////////////////////////////////////////////
+
+
+    // make sure the entity is known to Isis and is a root
+    void ensureRootObject(final Persistable pojo) {
+        final Oid oid = getAdapterManager().adapterFor(pojo).getOid();
+        if (!(oid instanceof RootOid)) {
+            throw new IsisException(MessageFormat.format("Not a RootOid: oid={0}, for {1}", oid, pojo));
+        }
+    }
+
+    private Version getVersionIfAny(final Persistable pojo) {
+        return Utils.getVersionIfAny(pojo, getAuthenticationSession());
+    }
+
+    @SuppressWarnings("unused")
+    private void ensureObjectNotLoaded(final Persistable pojo) {
+        final ObjectAdapter adapter = getAdapterManager().getAdapterFor(pojo);
+        if(adapter != null) {
+            final Oid oid = adapter.getOid();
+            throw new IsisException(MessageFormat.format("Object is already mapped in Isis: oid={0}, for {1}", oid, pojo));
+        }
+    }
+
+
+    
+    // /////////////////////////////////////////////////////////
+    // Dependencies (from context)
+    // /////////////////////////////////////////////////////////
+
+    protected AdapterManagerDefault getAdapterManager() {
+        return getPersistenceSession().getAdapterManager();
+    }
+
+    protected OidGenerator getOidGenerator() {
+        return getPersistenceSession().getOidGenerator();
+    }
+
+    protected PersistenceSession getPersistenceSession() {
+        return IsisContext.getPersistenceSession();
+    }
+
+    protected AuthenticationSession getAuthenticationSession() {
+        return IsisContext.getAuthenticationSession();
+    }
+
+    protected IsisTransaction getCurrentTransaction() {
+        return IsisContext.getCurrentTransaction();
+    }
+
+    protected PersistenceManager getJdoPersistenceManager() {
+        final ObjectStore objectStore = getObjectStore();
+        return objectStore.getPersistenceManager();
+    }
+
+    protected ObjectStore getObjectStore() {
+        return (ObjectStore) IsisContext.getPersistenceSession().getObjectStore();
+    }
+
+
+
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/d369891c/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/IsisLifecycleListener2.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/IsisLifecycleListener2.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/IsisLifecycleListener2.java
new file mode 100644
index 0000000..47e8383
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/IsisLifecycleListener2.java
@@ -0,0 +1,281 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.core.runtime.system.persistence;
+
+import java.util.Map;
+
+import javax.jdo.listener.AttachLifecycleListener;
+import javax.jdo.listener.ClearLifecycleListener;
+import javax.jdo.listener.CreateLifecycleListener;
+import javax.jdo.listener.DeleteLifecycleListener;
+import javax.jdo.listener.DetachLifecycleListener;
+import javax.jdo.listener.DirtyLifecycleListener;
+import javax.jdo.listener.InstanceLifecycleEvent;
+import javax.jdo.listener.LoadLifecycleListener;
+import javax.jdo.listener.StoreLifecycleListener;
+
+import com.google.common.collect.Maps;
+
+import org.datanucleus.enhancement.Persistable;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.core.runtime.system.persistence.FrameworkSynchronizer.CalledFrom;
+import org.apache.isis.objectstore.jdo.datanucleus.persistence.IsisLifecycleListener;
+
+public class IsisLifecycleListener2 implements AttachLifecycleListener, ClearLifecycleListener, CreateLifecycleListener, DeleteLifecycleListener, DetachLifecycleListener, DirtyLifecycleListener, LoadLifecycleListener, StoreLifecycleListener, SuspendableListener {
+
+    private final FrameworkSynchronizer synchronizer;
+
+    public IsisLifecycleListener2(FrameworkSynchronizer synchronizer) {
+        this.synchronizer = synchronizer;
+    }
+
+
+    /////////////////////////////////////////////////////////////////////////
+    // callbacks
+    /////////////////////////////////////////////////////////////////////////
+
+    @Override
+    public void postCreate(final InstanceLifecycleEvent event) {
+        withLogging(Phase.POST, event, new RunnableNoop(event));
+    }
+
+    @Override
+    public void preAttach(final InstanceLifecycleEvent event) {
+        withLogging(Phase.PRE, event, new RunnableEnsureRootObject(event));
+    }
+
+    @Override
+    public void postAttach(final InstanceLifecycleEvent event) {
+        withLogging(Phase.POST, event, new RunnableEnsureRootObject(event));
+    }
+
+    @Override
+    public void postLoad(final InstanceLifecycleEvent event) {
+        withLogging(Phase.POST, event, new RunnableAbstract(event){
+            @Override
+            protected void doRun() {
+                final Persistable pojo = Utils.persistenceCapableFor(event);
+                synchronizer.postLoadProcessingFor(pojo, CalledFrom.EVENT_LOAD);
+            }});
+    }
+
+	@Override
+    public void preStore(InstanceLifecycleEvent event) {
+        withLogging(Phase.PRE, event, new RunnableAbstract(event){
+            @Override
+            protected void doRun() {
+                final Persistable pojo = Utils.persistenceCapableFor(event);
+                synchronizer.preStoreProcessingFor(pojo, CalledFrom.EVENT_PRESTORE);
+
+            }});
+    }
+
+    @Override
+    public void postStore(InstanceLifecycleEvent event) {
+        withLogging(Phase.POST, event, new RunnableAbstract(event){
+            @Override
+            protected void doRun() {
+                final Persistable pojo = Utils.persistenceCapableFor(event);
+                synchronizer.postStoreProcessingFor(pojo, CalledFrom.EVENT_POSTSTORE);
+            }});
+    }
+
+    @Override
+    public void preDirty(InstanceLifecycleEvent event) {
+        withLogging(Phase.PRE, event, new RunnableAbstract(event){
+            @Override
+            protected void doRun() {
+                final Persistable pojo = Utils.persistenceCapableFor(event);
+                synchronizer.preDirtyProcessingFor(pojo, CalledFrom.EVENT_PREDIRTY);
+            }});
+    }
+
+    @Override
+    public void postDirty(InstanceLifecycleEvent event) {
+
+        // cannot assert on the frameworks being in agreement, due to the scenario documented
+        // in the FrameworkSynchronizer#preDirtyProcessing(...)
+        //
+        // 1<->m bidirectional, persistence-by-reachability
+
+        withLogging(Phase.POST, event, new RunnableNoop(event));
+    }
+
+    @Override
+    public void preDelete(InstanceLifecycleEvent event) {
+
+        withLogging(Phase.PRE, event, new RunnableAbstract(event){
+            @Override
+            protected void doRun() {
+                final Persistable pojo = Utils.persistenceCapableFor(event);
+                synchronizer.preDeleteProcessingFor(pojo, CalledFrom.EVENT_PREDELETE);
+            }
+        });
+    }
+
+    @Override
+    public void postDelete(InstanceLifecycleEvent event) {
+        withLogging(Phase.POST, event, new RunnableAbstract(event){
+            @Override
+            protected void doRun() {
+                final Persistable pojo = Utils.persistenceCapableFor(event);
+                synchronizer.postDeleteProcessingFor(pojo, CalledFrom.EVENT_POSTDELETE);
+            }
+        });
+    }
+
+    /**
+     * Does nothing, not important event for Isis to track.
+     */
+    @Override
+    public void preClear(InstanceLifecycleEvent event) {
+        // ignoring, not important to us
+    }
+
+    /**
+     * Does nothing, not important event for Isis to track.
+     */
+    @Override
+    public void postClear(InstanceLifecycleEvent event) {
+        // ignoring, not important to us
+    }
+
+    @Override
+    public void preDetach(InstanceLifecycleEvent event) {
+        withLogging(Phase.PRE, event, new RunnableEnsureRootObject(event));
+    }
+
+    @Override
+    public void postDetach(InstanceLifecycleEvent event) {
+        withLogging(Phase.POST, event, new RunnableEnsureRootObject(event));
+    }
+
+    
+    /////////////////////////////////////////////////////////////////////////
+    // withLogging
+    /////////////////////////////////////////////////////////////////////////
+
+    private void withLogging(Phase phase, InstanceLifecycleEvent event, Runnable runnable) {
+        if (IsisLifecycleListener.LOG.isDebugEnabled()) {
+            IsisLifecycleListener.LOG.debug(logString(phase, LoggingLocation.ENTRY, event));
+        }
+        try {
+            runnable.run();
+        } finally {
+            if (IsisLifecycleListener.LOG.isDebugEnabled()) {
+                IsisLifecycleListener.LOG.debug(logString(phase, LoggingLocation.EXIT, event));
+            }
+        }
+    }
+    
+    private abstract class RunnableAbstract implements Runnable {
+        final InstanceLifecycleEvent event;
+        public RunnableAbstract(final InstanceLifecycleEvent event) {
+            this.event = event;
+        }
+        @Override
+        public void run() {
+            if (isSuspended()) {
+                if (IsisLifecycleListener.LOG.isDebugEnabled()) {
+                    IsisLifecycleListener.LOG.debug(" [currently suspended - ignoring]");
+                }
+                return;
+            }
+            doRun();
+        }
+        
+        protected abstract void doRun(); 
+    }
+    
+    private class RunnableNoop extends RunnableAbstract {
+        RunnableNoop(InstanceLifecycleEvent event) {
+            super(event);
+        }
+        protected void doRun() {} 
+    }
+    
+    private class RunnableEnsureRootObject extends RunnableAbstract {
+        RunnableEnsureRootObject(InstanceLifecycleEvent event) {
+            super(event);
+        }
+        protected void doRun() {
+            final Persistable pojo = Utils.persistenceCapableFor(event);
+            synchronizer.ensureRootObject(pojo);
+        }
+    }
+    
+
+    // /////////////////////////////////////////////////////////
+    // SuspendListener
+    // /////////////////////////////////////////////////////////
+
+    private boolean suspended;
+
+
+    @Override
+    public boolean isSuspended() {
+        return suspended;
+    }
+
+    @Override
+    public void setSuspended(boolean suspended) {
+        this.suspended = suspended;
+    }
+
+    // /////////////////////////////////////////////////////////
+    // Logging
+    // /////////////////////////////////////////////////////////
+
+    private enum Phase {
+        PRE, POST
+    }
+
+    private static Map<Integer, LifecycleEventType> events = Maps.newHashMap();
+
+    private enum LifecycleEventType {
+        CREATE(0), LOAD(1), STORE(2), CLEAR(3), DELETE(4), DIRTY(5), DETACH(6), ATTACH(7);
+
+        private LifecycleEventType(int code) {
+            events.put(code, this);
+        }
+
+        public static LifecycleEventType lookup(int code) {
+            return events.get(code);
+        }
+    }
+
+    private String logString(Phase phase, LoggingLocation location, InstanceLifecycleEvent event) {
+        final Persistable pojo = Utils.persistenceCapableFor(event);
+        final AdapterManager adapterManager = getAdapterManager();
+        final ObjectAdapter adapter = adapterManager.getAdapterFor(pojo);
+        return phase + " " + location.prefix + " " + LifecycleEventType.lookup(event.getEventType()) + ": oid=" + (adapter !=null? adapter.getOid(): "(null)") + " ,pojo " + pojo;
+    }
+
+    
+    // /////////////////////////////////////////////////////////
+    // Dependencies (from context)
+    // /////////////////////////////////////////////////////////
+
+    protected AdapterManager getAdapterManager() {
+        return IsisContext.getPersistenceSession().getAdapterManager();
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/d369891c/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/LoggingLocation.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/LoggingLocation.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/LoggingLocation.java
new file mode 100644
index 0000000..dbad765
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/LoggingLocation.java
@@ -0,0 +1,27 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.core.runtime.system.persistence;
+
+public enum LoggingLocation {
+    ENTRY(">>"), EXIT("<<");
+    final String prefix;
+    private LoggingLocation(String prefix) {
+        this.prefix = prefix;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/d369891c/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/ObjectStore.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/ObjectStore.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/ObjectStore.java
index 082958c..3866e50 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/ObjectStore.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/ObjectStore.java
@@ -59,9 +59,7 @@ import org.apache.isis.core.runtime.runner.opts.OptionHandlerFixtureAbstract;
 import org.apache.isis.core.runtime.system.context.IsisContext;
 import org.apache.isis.core.runtime.system.transaction.IsisTransaction;
 import org.apache.isis.core.runtime.system.transaction.IsisTransactionManager;
-import org.apache.isis.objectstore.jdo.datanucleus.DataNucleusApplicationComponents;
-import org.apache.isis.objectstore.jdo.datanucleus.persistence.FrameworkSynchronizer;
-import org.apache.isis.objectstore.jdo.datanucleus.persistence.FrameworkSynchronizer.CalledFrom;
+import org.apache.isis.core.runtime.system.persistence.FrameworkSynchronizer.CalledFrom;
 import org.apache.isis.objectstore.jdo.datanucleus.persistence.commands.DataNucleusCreateObjectCommand;
 import org.apache.isis.objectstore.jdo.datanucleus.persistence.commands.DataNucleusDeleteObjectCommand;
 import org.apache.isis.objectstore.jdo.datanucleus.persistence.queries.PersistenceQueryFindAllInstancesProcessor;

http://git-wip-us.apache.org/repos/asf/isis/blob/d369891c/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession.java
index 15a370b..bde091e 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession.java
@@ -58,7 +58,6 @@ import org.apache.isis.core.runtime.persistence.objectstore.transaction.DestroyO
 import org.apache.isis.core.runtime.system.transaction.IsisTransactionManager;
 import org.apache.isis.core.runtime.system.transaction.TransactionalClosureAbstract;
 import org.apache.isis.core.runtime.system.transaction.TransactionalClosureWithReturnAbstract;
-import org.apache.isis.objectstore.jdo.datanucleus.DataNucleusApplicationComponents;
 
 import static org.apache.isis.core.commons.ensure.Ensure.ensureThatArg;
 import static org.apache.isis.core.commons.ensure.Ensure.ensureThatState;

http://git-wip-us.apache.org/repos/asf/isis/blob/d369891c/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactory.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactory.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactory.java
index 3f10ebf..d18bb7a 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactory.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactory.java
@@ -41,7 +41,6 @@ import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorCom
 import org.apache.isis.core.runtime.persistence.FixturesInstalledFlag;
 import org.apache.isis.core.runtime.persistence.internal.RuntimeContextFromSession;
 import org.apache.isis.core.runtime.system.DeploymentType;
-import org.apache.isis.objectstore.jdo.datanucleus.DataNucleusApplicationComponents;
 import org.apache.isis.objectstore.jdo.datanucleus.DataNucleusPersistenceMechanismInstaller;
 import org.apache.isis.objectstore.jdo.datanucleus.JDOStateManagerForIsis;
 import org.apache.isis.objectstore.jdo.metamodel.facets.object.auditable.AuditableAnnotationInJdoApplibFacetFactory;

http://git-wip-us.apache.org/repos/asf/isis/blob/d369891c/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/SuspendableListener.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/SuspendableListener.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/SuspendableListener.java
new file mode 100644
index 0000000..47d8c02
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/SuspendableListener.java
@@ -0,0 +1,27 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.core.runtime.system.persistence;
+
+public interface SuspendableListener {
+
+    boolean isSuspended();
+
+    void setSuspended(boolean suspend);
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/d369891c/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/Utils.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/Utils.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/Utils.java
new file mode 100644
index 0000000..2996f7b
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/Utils.java
@@ -0,0 +1,50 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.core.runtime.system.persistence;
+
+import javax.jdo.listener.InstanceLifecycleEvent;
+
+import org.datanucleus.enhancement.Persistable;
+
+import org.apache.isis.core.commons.authentication.AuthenticationSession;
+import org.apache.isis.core.metamodel.adapter.version.SerialNumberVersion;
+import org.apache.isis.core.metamodel.adapter.version.Version;
+
+public class Utils {
+
+    @SuppressWarnings("unused")
+    private static Object jdoObjectIdFor(InstanceLifecycleEvent event) {
+        Persistable persistenceCapable = Utils.persistenceCapableFor(event);
+        Object jdoObjectId = persistenceCapable.dnGetObjectId();
+        return jdoObjectId;
+    }
+
+    static Persistable persistenceCapableFor(InstanceLifecycleEvent event) {
+        return (Persistable)event.getSource();
+    }
+
+    static Version getVersionIfAny(final Persistable pojo, final AuthenticationSession authenticationSession) {
+        Object jdoVersion = pojo.dnGetVersion();
+        if(jdoVersion instanceof Long) {
+            return SerialNumberVersion.create((Long) jdoVersion, authenticationSession.getUserName(), null); 
+        } 
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/d369891c/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/CreateSchemaObjectFromClassMetadata.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/CreateSchemaObjectFromClassMetadata.java b/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/CreateSchemaObjectFromClassMetadata.java
index 5059604..317ffc7 100644
--- a/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/CreateSchemaObjectFromClassMetadata.java
+++ b/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/CreateSchemaObjectFromClassMetadata.java
@@ -25,8 +25,6 @@ import java.sql.SQLException;
 import java.sql.Statement;
 import java.util.Map;
 
-import javax.jdo.PersistenceManagerFactory;
-
 import com.google.common.base.Strings;
 
 import org.datanucleus.metadata.AbstractClassMetaData;
@@ -37,15 +35,11 @@ import org.slf4j.LoggerFactory;
 /**
  * Implementation note: the methods in this class are <tt>protected</tt> to allow for easy subclassing.
  */
-public class CreateSchemaObjectFromClassMetadata implements MetaDataListener, PersistenceManagerFactoryAware, DataNucleusPropertiesAware {
+public class CreateSchemaObjectFromClassMetadata implements MetaDataListener, DataNucleusPropertiesAware {
 
     private static final Logger LOG = LoggerFactory.getLogger(DataNucleusPersistenceMechanismInstaller.class);
 
     //region > persistenceManagerFactory, properties
-    private PersistenceManagerFactory persistenceManagerFactory;
-    protected PersistenceManagerFactory getPersistenceManagerFactory() {
-        return persistenceManagerFactory;
-    }
 
     private Map<String, String> properties;
     protected Map<String, String> getProperties() {
@@ -177,10 +171,6 @@ public class CreateSchemaObjectFromClassMetadata implements MetaDataListener, Pe
     //endregion
 
     //region > injected dependencies
-    public void setPersistenceManagerFactory(final PersistenceManagerFactory persistenceManagerFactory) {
-        this.persistenceManagerFactory = persistenceManagerFactory;
-    }
-
     @Override
     public void setDataNucleusProperties(final Map<String, String> properties) {
         this.properties = properties;

http://git-wip-us.apache.org/repos/asf/isis/blob/d369891c/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusApplicationComponents.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusApplicationComponents.java b/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusApplicationComponents.java
deleted file mode 100644
index 2575569..0000000
--- a/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusApplicationComponents.java
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.isis.objectstore.jdo.datanucleus;
-
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-
-import javax.jdo.JDOHelper;
-import javax.jdo.PersistenceManager;
-import javax.jdo.PersistenceManagerFactory;
-
-import com.google.common.base.Joiner;
-import com.google.common.collect.Maps;
-
-import org.datanucleus.PersistenceNucleusContext;
-import org.datanucleus.PropertyNames;
-import org.datanucleus.api.jdo.JDOPersistenceManagerFactory;
-import org.datanucleus.metadata.MetaDataListener;
-import org.datanucleus.metadata.MetaDataManager;
-import org.datanucleus.store.StoreManager;
-import org.datanucleus.store.schema.SchemaAwareStoreManager;
-
-import org.apache.isis.core.commons.components.ApplicationScopedComponent;
-import org.apache.isis.core.commons.config.IsisConfiguration;
-import org.apache.isis.core.commons.factory.InstanceUtil;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-import org.apache.isis.core.runtime.system.context.IsisContext;
-import org.apache.isis.objectstore.jdo.datanucleus.persistence.FrameworkSynchronizer;
-import org.apache.isis.objectstore.jdo.datanucleus.persistence.IsisLifecycleListener;
-import org.apache.isis.objectstore.jdo.metamodel.facets.object.query.JdoNamedQuery;
-import org.apache.isis.objectstore.jdo.metamodel.facets.object.query.JdoQueryFacet;
-
-public class DataNucleusApplicationComponents implements ApplicationScopedComponent {
-
-
-    ///////////////////////////////////////////////////////////////////////////
-    // JRebel support
-    ///////////////////////////////////////////////////////////////////////////
-
-    private static DataNucleusApplicationComponents instance;
-    
-    /**
-     * For JRebel plugin
-     */
-    public static MetaDataManager getMetaDataManager() {
-        return instance != null
-                ? ((JDOPersistenceManagerFactory)instance.persistenceManagerFactory).getNucleusContext().getMetaDataManager() 
-                : null;
-    }
-
-    public static void markAsStale() {
-        if(instance != null) {
-            instance.stale = true;
-        }
-    }
-
-    private boolean stale = false;
-    public boolean isStale() {
-        return stale;
-    }
-
-    ///////////////////////////////////////////////////////////////////////////
-
-    private final Set<String> persistableClassNameSet;
-    private final IsisConfiguration jdoObjectstoreConfig;
-    private final Map<String, String> datanucleusProps;
-    
-    private final IsisLifecycleListener lifecycleListener;
-    private final FrameworkSynchronizer synchronizer;
-    
-    private Map<String, JdoNamedQuery> namedQueryByName;
-    private PersistenceManagerFactory persistenceManagerFactory;
-
-    public DataNucleusApplicationComponents(
-            final IsisConfiguration jdoObjectstoreConfig,
-            final Map<String, String> datanucleusProps,
-            final Set<String> persistableClassNameSet) {
-    
-        this.datanucleusProps = datanucleusProps;
-        this.persistableClassNameSet = persistableClassNameSet;
-        this.jdoObjectstoreConfig = jdoObjectstoreConfig;
-
-        this.synchronizer = new FrameworkSynchronizer();
-        this.lifecycleListener = new IsisLifecycleListener(synchronizer);
-
-        initialize();
-        
-        // for JRebel plugin
-        instance = this;
-    }
-
-    private void initialize() {
-        persistenceManagerFactory = createPmfAndSchemaIfRequired(persistableClassNameSet, datanucleusProps);
-
-        namedQueryByName = catalogNamedQueries(persistableClassNameSet);
-    }
-
-    private static boolean isSchemaAwareStoreManager(Map<String,String> datanucleusProps) {
-
-        // we create a throw-away instance of PMF so that we can probe whether DN has
-        // been configured with a schema-aware store manager or not.
-        final JDOPersistenceManagerFactory probePmf =
-                (JDOPersistenceManagerFactory)JDOHelper.getPersistenceManagerFactory(datanucleusProps);
-        try {
-            final PersistenceNucleusContext nucleusContext = probePmf.getNucleusContext();
-            final StoreManager storeManager = nucleusContext.getStoreManager();
-            return storeManager instanceof SchemaAwareStoreManager;
-        } finally {
-            probePmf.close();
-        }
-    }
-
-    // REF: http://www.datanucleus.org/products/datanucleus/jdo/schema.html
-    private PersistenceManagerFactory createPmfAndSchemaIfRequired(final Set<String> persistableClassNameSet, final Map<String, String> datanucleusProps) {
-
-        PersistenceManagerFactory persistenceManagerFactory;
-        if(isSchemaAwareStoreManager(datanucleusProps)) {
-
-            // rather than reinvent too much of the wheel, we reuse the same property that DN would check
-            // for if it were doing the auto-creation itself (read from isis.properties)
-            final boolean createSchema = isSet(datanucleusProps, PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_ALL);
-
-            if(createSchema) {
-
-                // we *don't* use DN's eager loading (autoStart), because doing so means that it attempts to
-                // create the table before the schema (for any entities annotated @PersistenceCapable(schema=...)
-                //
-                // instead, we manually create the schema ourselves
-                // (if the configured StoreMgr supports it, and if requested in isis.properties)
-                //
-                datanucleusProps.put(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_ALL, "false"); // turn off, cos want to do the schema object ourselves...
-                datanucleusProps.put(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_SCHEMA, "false");
-                datanucleusProps.put(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_TABLES, "true"); // but have DN do everything else...
-                datanucleusProps.put(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_COLUMNS, "true");
-                datanucleusProps.put(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_CONSTRAINTS, "true");
-
-                persistenceManagerFactory = JDOHelper.getPersistenceManagerFactory(datanucleusProps);
-                createSchema(persistenceManagerFactory, persistableClassNameSet, datanucleusProps);
-
-            } else {
-                persistenceManagerFactory = JDOHelper.getPersistenceManagerFactory(datanucleusProps);
-            }
-
-        } else {
-
-            // we *DO* use DN's eager loading (autoStart), because it seems that DN requires this (for neo4j at least)
-            // otherwise NPEs occur later.
-
-            configureAutoStart(persistableClassNameSet, datanucleusProps);
-            persistenceManagerFactory = JDOHelper.getPersistenceManagerFactory(this.datanucleusProps);
-        }
-
-        return persistenceManagerFactory;
-
-    }
-
-    private void configureAutoStart(final Set<String> persistableClassNameSet, final Map<String, String> datanucleusProps) {
-        final String persistableClassNames = Joiner.on(',').join(persistableClassNameSet);
-
-        // ref: http://www.datanucleus.org/products/datanucleus/jdo/autostart.html
-        datanucleusProps.put(PropertyNames.PROPERTY_AUTOSTART_MECHANISM, "Classes");
-        datanucleusProps.put(PropertyNames.PROPERTY_AUTOSTART_MODE, "Checked");
-        datanucleusProps.put(PropertyNames.PROPERTY_AUTOSTART_CLASSNAMES, persistableClassNames);
-    }
-
-    private void createSchema(
-            final PersistenceManagerFactory persistenceManagerFactory,
-            final Set<String> persistableClassNameSet,
-            final Map<String, String> datanucleusProps) {
-
-        JDOPersistenceManagerFactory jdopmf = (JDOPersistenceManagerFactory) persistenceManagerFactory;
-        final PersistenceNucleusContext nucleusContext = jdopmf.getNucleusContext();
-        final SchemaAwareStoreManager schemaAwareStoreManager = (SchemaAwareStoreManager)nucleusContext.getStoreManager();
-
-        final MetaDataManager metaDataManager = nucleusContext.getMetaDataManager();
-
-        registerMetadataListener(metaDataManager, persistenceManagerFactory, datanucleusProps);
-
-        schemaAwareStoreManager.createSchemaForClasses(persistableClassNameSet, asProperties(datanucleusProps));
-    }
-
-    private boolean isSet(final Map<String, String> props, final String key) {
-        return Boolean.parseBoolean( props.get(key) );
-    }
-
-    private void registerMetadataListener(final MetaDataManager metaDataManager, final PersistenceManagerFactory persistenceManagerFactory, final Map<String, String> datanucleusProps) {
-        final MetaDataListener listener = createMetaDataListener();
-        if(listener == null) {
-            return;
-        }
-
-        if(listener instanceof PersistenceManagerFactoryAware) {
-            ((PersistenceManagerFactoryAware) listener).setPersistenceManagerFactory(persistenceManagerFactory);
-        }
-
-        if(listener instanceof DataNucleusPropertiesAware) {
-            ((DataNucleusPropertiesAware) listener).setDataNucleusProperties(datanucleusProps);
-        }
-
-
-        // and install the listener for any classes that are lazily loaded subsequently
-        // (shouldn't be any, this is mostly backwards compatibility with previous design).
-        metaDataManager.registerListener(listener);
-    }
-
-    private MetaDataListener createMetaDataListener() {
-        final String classMetadataListenerClassName = jdoObjectstoreConfig.getString(
-                DataNucleusPersistenceMechanismInstaller.CLASS_METADATA_LOADED_LISTENER_KEY,
-                DataNucleusPersistenceMechanismInstaller.CLASS_METADATA_LOADED_LISTENER_DEFAULT);
-        return classMetadataListenerClassName != null
-                ? InstanceUtil.createInstance(classMetadataListenerClassName, MetaDataListener.class)
-                : null;
-    }
-
-
-    private static Properties asProperties(final Map<String, String> props) {
-        final Properties properties = new Properties();
-        properties.putAll(props);
-        return properties;
-    }
-
-    private static Map<String, JdoNamedQuery> catalogNamedQueries(Set<String> persistableClassNames) {
-        final Map<String, JdoNamedQuery> namedQueryByName = Maps.newHashMap();
-        for (final String persistableClassName: persistableClassNames) {
-            final ObjectSpecification spec = IsisContext.getSpecificationLoader().loadSpecification(persistableClassName);
-            final JdoQueryFacet facet = spec.getFacet(JdoQueryFacet.class);
-            if (facet == null) {
-                continue;
-            }
-            for (final JdoNamedQuery namedQuery : facet.getNamedQueries()) {
-                namedQueryByName.put(namedQuery.getName(), namedQuery);
-            }
-        }
-        return namedQueryByName;
-    }
-    
-    public PersistenceManagerFactory getPersistenceManagerFactory() {
-        return persistenceManagerFactory;
-    }
-
-    ///////////////////////////////////////////////////////////////////////////
-    //
-    ///////////////////////////////////////////////////////////////////////////
-
-    @Override
-    public void init() {
-    }
-
-    @Override
-    public void shutdown() {
-    }
-
-
-    ///////////////////////////////////////////////////////////////////////////
-    // FrameworkSynchronizer
-    ///////////////////////////////////////////////////////////////////////////
-
-    public FrameworkSynchronizer getFrameworkSynchronizer() {
-        return synchronizer;
-    }
-
-
-    ///////////////////////////////////////////////////////////////////////////
-    //
-    ///////////////////////////////////////////////////////////////////////////
-    
-    public PersistenceManager createPersistenceManager() {
-        PersistenceManager persistenceManager = persistenceManagerFactory.getPersistenceManager();
-        
-        persistenceManager.addInstanceLifecycleListener(lifecycleListener, (Class[])null);
-        return persistenceManager;
-    }
-
-    public JdoNamedQuery getNamedQuery(String queryName) {
-        return namedQueryByName.get(queryName);
-    }
-
-    
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/d369891c/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusPersistenceMechanismInstaller.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusPersistenceMechanismInstaller.java b/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusPersistenceMechanismInstaller.java
index 1dbd153..fad3876 100644
--- a/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusPersistenceMechanismInstaller.java
+++ b/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusPersistenceMechanismInstaller.java
@@ -57,9 +57,6 @@ public class DataNucleusPersistenceMechanismInstaller extends InstallerAbstract
 
     public static final String NAME = "datanucleus";
 
-    public static final String CLASS_METADATA_LOADED_LISTENER_KEY = "classMetadataLoadedListener";
-    static final String CLASS_METADATA_LOADED_LISTENER_DEFAULT = CreateSchemaObjectFromClassMetadata.class.getName();
-
     public static final String JDO_OBJECTSTORE_CONFIG_PREFIX = "isis.persistor.datanucleus";  // specific to the JDO objectstore
     public static final String DATANUCLEUS_CONFIG_PREFIX = "isis.persistor.datanucleus.impl"; // reserved for datanucleus' own config props
 

http://git-wip-us.apache.org/repos/asf/isis/blob/d369891c/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/PersistenceManagerFactoryAware.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/PersistenceManagerFactoryAware.java b/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/PersistenceManagerFactoryAware.java
deleted file mode 100644
index 887af87..0000000
--- a/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/PersistenceManagerFactoryAware.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.isis.objectstore.jdo.datanucleus;
-
-import javax.jdo.PersistenceManagerFactory;
-
-public interface PersistenceManagerFactoryAware {
-
-    public void setPersistenceManagerFactory(final PersistenceManagerFactory persistenceManagerFactory);
-}