You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2020/01/03 18:26:18 UTC

[isis] branch master updated: ISIS-2248: Store the MetaModelContext in DN's NucleusContext

This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git


The following commit(s) were added to refs/heads/master by this push:
     new 12635c4  ISIS-2248: Store the MetaModelContext in DN's NucleusContext
12635c4 is described below

commit 12635c4fbd0e71a38d84a6bd032a14a58c52ee9c
Author: Andi Huber <ah...@apache.org>
AuthorDate: Fri Jan 3 19:26:06 2020 +0100

    ISIS-2248: Store the MetaModelContext in DN's NucleusContext
    
    this allows for JDOStateManagerForIsis not to rely on
    IsisContext.getCurrentIsisSession()
---
 .../CreateSchemaObjectFromClassMetadata.java       | 28 +++++------
 .../datanucleus/DataNucleusPropertiesAware.java    |  2 +-
 .../datanucleus/DataNucleusSettings.java           |  6 +--
 .../datanucleus/JDOStateManagerForIsis.java        | 57 ++++++++++++++++------
 .../JdoStoreLifecycleListenerForIsis.java          |  4 +-
 .../metrics/MetricsServiceDefault.java             | 33 ++++++-------
 .../persistence/DNStoreManagerType.java            | 10 ++--
 .../DataNucleusApplicationComponents5.java         | 34 ++++++++-----
 .../persistence/PersistenceSessionFactory5.java    | 23 ++++++---
 9 files changed, 116 insertions(+), 81 deletions(-)

diff --git a/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/datanucleus/CreateSchemaObjectFromClassMetadata.java b/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/datanucleus/CreateSchemaObjectFromClassMetadata.java
index 0ca1036..30fd9a0 100644
--- a/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/datanucleus/CreateSchemaObjectFromClassMetadata.java
+++ b/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/datanucleus/CreateSchemaObjectFromClassMetadata.java
@@ -41,13 +41,7 @@ import lombok.extern.log4j.Log4j2;
 @Log4j2
 public class CreateSchemaObjectFromClassMetadata implements MetaDataListener, DataNucleusPropertiesAware {
 
-    // -- persistenceManagerFactory, properties
-
-    private Map<String, String> properties;
-    protected Map<String, String> getProperties() {
-        return properties;
-    }
-
+    private Map<String, Object> properties;
 
     // -- loaded (API)
 
@@ -62,9 +56,9 @@ public class CreateSchemaObjectFromClassMetadata implements MetaDataListener, Da
         Connection connection = null;
         Statement statement = null;
 
-        final String driverName = properties.get("javax.jdo.option.ConnectionDriverName");
-        final String url = properties.get("javax.jdo.option.ConnectionURL");
-        final String userName = properties.get("javax.jdo.option.ConnectionUserName");
+        final String driverName = getPropertyAsString("javax.jdo.option.ConnectionDriverName");
+        final String url = getPropertyAsString("javax.jdo.option.ConnectionURL");
+        final String userName = getPropertyAsString("javax.jdo.option.ConnectionUserName");
         final String password = getConnectionPassword();
 
         if(_Strings.isNullOrEmpty(driverName) || _Strings.isNullOrEmpty(url)) {
@@ -93,6 +87,8 @@ public class CreateSchemaObjectFromClassMetadata implements MetaDataListener, Da
     }
 
 
+
+
     // -- skip, exec, schemaNameFor
 
     /**
@@ -144,7 +140,7 @@ public class CreateSchemaObjectFromClassMetadata implements MetaDataListener, Da
         // db vendors without requiring lots of complex configuration of DataNucleus
         //
 
-        String url = getProperties().get("javax.jdo.option.ConnectionURL");
+        String url = getPropertyAsString("javax.jdo.option.ConnectionURL");
 
         if(url.contains("postgres")) {
             // in DN 4.0, was forcing lower case:
@@ -184,10 +180,10 @@ public class CreateSchemaObjectFromClassMetadata implements MetaDataListener, Da
      * @return Password
      */
     private String getConnectionPassword() {
-        String password = properties.get("javax.jdo.option.ConnectionPassword");
+        String password = getPropertyAsString("javax.jdo.option.ConnectionPassword");
         if (password != null)
         {
-            String decrypterName = properties.get("datanucleus.ConnectionPasswordDecrypter");
+            String decrypterName = getPropertyAsString("datanucleus.ConnectionPasswordDecrypter");
             if (decrypterName != null)
             {
                 // Decrypt the password using the provided class
@@ -210,10 +206,14 @@ public class CreateSchemaObjectFromClassMetadata implements MetaDataListener, Da
 
     // -- injected dependencies
     @Override
-    public void setDataNucleusProperties(final Map<String, String> properties) {
+    public void setDataNucleusProperties(final Map<String, Object> properties) {
         this.properties = properties;
     }
 
+    
+    private String getPropertyAsString(String key) {
+        return (String) properties.get(key);
+    }
 
 
 }
diff --git a/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/datanucleus/DataNucleusPropertiesAware.java b/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/datanucleus/DataNucleusPropertiesAware.java
index 477322e..e954e3c 100644
--- a/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/datanucleus/DataNucleusPropertiesAware.java
+++ b/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/datanucleus/DataNucleusPropertiesAware.java
@@ -22,5 +22,5 @@ import java.util.Map;
 
 public interface DataNucleusPropertiesAware {
 
-    public void setDataNucleusProperties(final Map<String, String> properties);
+    public void setDataNucleusProperties(final Map<String, Object> properties);
 }
diff --git a/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/datanucleus/DataNucleusSettings.java b/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/datanucleus/DataNucleusSettings.java
index 6ac0a19..04bf323 100644
--- a/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/datanucleus/DataNucleusSettings.java
+++ b/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/datanucleus/DataNucleusSettings.java
@@ -18,19 +18,18 @@
  */
 package org.apache.isis.persistence.jdo.datanucleus5.datanucleus;
 
-import lombok.extern.log4j.Log4j2;
-
 import java.util.Map;
 
 import javax.inject.Inject;
 import javax.inject.Named;
 
-import org.apache.isis.applib.annotation.OrderPrecedence;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.context.annotation.Primary;
 import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Service;
 
+import org.apache.isis.applib.annotation.OrderPrecedence;
+
 /**
  * @since 2.0
  */
@@ -39,7 +38,6 @@ import org.springframework.stereotype.Service;
 @Order(OrderPrecedence.HIGH)
 @Primary
 @Qualifier("Default")
-@Log4j2
 public class DataNucleusSettings {
 
     @Inject @Named("dn-settings") 
diff --git a/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/datanucleus/JDOStateManagerForIsis.java b/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/datanucleus/JDOStateManagerForIsis.java
index 2983513..bdc42a6 100644
--- a/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/datanucleus/JDOStateManagerForIsis.java
+++ b/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/datanucleus/JDOStateManagerForIsis.java
@@ -19,8 +19,6 @@
 
 package org.apache.isis.persistence.jdo.datanucleus5.datanucleus;
 
-import org.apache.isis.runtime.context.IsisContext;
-import org.apache.isis.runtime.session.IsisSession;
 import org.datanucleus.ExecutionContext;
 import org.datanucleus.cache.CachedPC;
 import org.datanucleus.enhancement.Persistable;
@@ -30,31 +28,36 @@ import org.datanucleus.store.FieldValues;
 import org.datanucleus.store.fieldmanager.FieldManager;
 
 import org.apache.isis.applib.services.inject.ServiceInjector;
+import org.apache.isis.metamodel.context.MetaModelContext;
 import org.apache.isis.persistence.jdo.datanucleus5.datanucleus.service.eventbus.EventBusServiceJdo;
 
+import lombok.val;
 import lombok.extern.log4j.Log4j2;
 
-import java.util.Optional;
-
 /**
- * Although injection into domain objects is considered by some "unusual"
+ * DataNucleus extension point in support of injection into entities. 
+ * 
+ * @apiNote Although injection into domain objects is considered by some "unusual"
  * (see eg https://stackoverflow.com/a/11648163/9269480)
  * it has always been supported by the Apache Isis framework as one of the
- * main mechanisms in support of "behaviourally complete" objects.
+ * main mechanisms in support of "behaviorally complete" objects.
  */
 @Log4j2
 public class JDOStateManagerForIsis extends ReferentialStateManagerImpl {
 
+    public static enum Hint {
+        NONE,
+        REPLACE_FIELDS,
+        POST_COMMIT
+    }
+    
+    private ServiceInjector serviceInjector;
+    
     public JDOStateManagerForIsis(
             final ExecutionContext ec,
             final AbstractClassMetaData cmd) {
         super(ec, cmd);
-    }
-
-    public enum Hint {
-        NONE,
-        REPLACE_FIELDS,
-        POST_COMMIT
+        initServiceInjector(extractMetaModelContext(ec));
     }
 
     /**
@@ -228,12 +231,34 @@ public class JDOStateManagerForIsis extends ReferentialStateManagerImpl {
     }
 
     protected void injectServicesInto(Persistable pc) {
-        final Optional<IsisSession> isisSessionIfAny = IsisContext.getCurrentIsisSession();
-        if(isisSessionIfAny.isPresent()) {
-            isisSessionIfAny.get().getServiceInjector().injectServicesInto(pc);
+        if(serviceInjector!=null) {
+            serviceInjector.injectServicesInto(pc);
         } else {
-            log.warn("could not inject into PC, no isis session");
+            log.warn("could not inject into entity, no service injector");
+        }
+    }
+    
+    // -- HELPER
+    
+    private MetaModelContext extractMetaModelContext(ExecutionContext ec) {
+        
+        return (MetaModelContext) ec.getNucleusContext()
+                .getConfiguration()
+                .getPersistenceProperties()
+                .get("isis.metamodelcontext");
+    }
+    
+    private void initServiceInjector(MetaModelContext metaModelContext) {
+        
+        if(metaModelContext!=null) {
+            this.serviceInjector = metaModelContext.getServiceInjector();
+        }
+        
+        if(this.serviceInjector==null) {
+            log.warn("could not retrieve a ServiceInjector from the ExecutionContext");
         }
     }
     
+    
+    
 }
diff --git a/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/lifecycles/JdoStoreLifecycleListenerForIsis.java b/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/lifecycles/JdoStoreLifecycleListenerForIsis.java
index b208777..03e4a81 100644
--- a/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/lifecycles/JdoStoreLifecycleListenerForIsis.java
+++ b/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/lifecycles/JdoStoreLifecycleListenerForIsis.java
@@ -45,8 +45,8 @@ javax.jdo.listener.StoreLifecycleListener {
 
         val persistableObject = instanceEvent.getPersistentInstance();
 
-        if(persistableObject!=null && 
-                JdoMetamodelUtil.isPersistenceEnhanced(persistableObject.getClass())) {
+        if(persistableObject!=null 
+                && JdoMetamodelUtil.isPersistenceEnhanced(persistableObject.getClass())) {
 
             val event = PreStoreEvent.of(persistableObject);
             persistenceEventService.firePreStoreEvent(event);
diff --git a/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/metrics/MetricsServiceDefault.java b/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/metrics/MetricsServiceDefault.java
index 0279a43..69ec3c0 100644
--- a/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/metrics/MetricsServiceDefault.java
+++ b/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/metrics/MetricsServiceDefault.java
@@ -18,9 +18,7 @@
  */
 package org.apache.isis.persistence.jdo.datanucleus5.metrics;
 
-import lombok.extern.log4j.Log4j2;
-
-import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.LongAdder;
 
 import javax.enterprise.context.RequestScoped;
 import javax.inject.Inject;
@@ -29,31 +27,32 @@ import javax.jdo.listener.InstanceLifecycleEvent;
 import javax.jdo.listener.InstanceLifecycleListener;
 import javax.jdo.listener.LoadLifecycleListener;
 
-import org.apache.isis.applib.annotation.OrderPrecedence;
-import org.apache.isis.applib.services.WithTransactionScope;
-import org.apache.isis.applib.services.metrics.MetricsService;
-import org.apache.isis.runtime.persistence.transaction.ChangedObjectsService;
-
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.context.annotation.Primary;
 import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Service;
 
+import org.apache.isis.applib.annotation.OrderPrecedence;
+import org.apache.isis.applib.services.WithTransactionScope;
+import org.apache.isis.applib.services.metrics.MetricsService;
+import org.apache.isis.runtime.persistence.transaction.ChangedObjectsService;
+
 @Service
 @Named("isisJdoDn5.MetricsServiceDefault")
 @Order(OrderPrecedence.MIDPOINT)
 @Primary
 @Qualifier("Default")
 @RequestScoped
-@Log4j2
-public class MetricsServiceDefault implements MetricsService, InstanceLifecycleListener,
-LoadLifecycleListener, WithTransactionScope {
+public class MetricsServiceDefault 
+implements MetricsService, InstanceLifecycleListener, LoadLifecycleListener, WithTransactionScope {
 
-    private AtomicInteger numberLoaded = new AtomicInteger(0);
+    @Inject private ChangedObjectsService changedObjectsServiceInternal;
+    
+    private LongAdder numberLoaded = new LongAdder();
 
     @Override
     public int numberObjectsLoaded() {
-        return numberLoaded.get();
+        return Math.toIntExact(numberLoaded.longValue());
     }
 
     @Override
@@ -63,7 +62,7 @@ LoadLifecycleListener, WithTransactionScope {
 
     @Override
     public void postLoad(final InstanceLifecycleEvent event) {
-        numberLoaded.incrementAndGet();
+        numberLoaded.increment();
     }
 
     /**
@@ -72,10 +71,8 @@ LoadLifecycleListener, WithTransactionScope {
      */
     @Override
     public void resetForNextTransaction() {
-        numberLoaded.set(0);
+        numberLoaded.reset();
     }
-
-    @Inject
-    ChangedObjectsService changedObjectsServiceInternal;
+    
 
 }
diff --git a/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/persistence/DNStoreManagerType.java b/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/persistence/DNStoreManagerType.java
index 474384f..6a8ba4d 100644
--- a/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/persistence/DNStoreManagerType.java
+++ b/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/persistence/DNStoreManagerType.java
@@ -42,7 +42,7 @@ enum DNStoreManagerType {
     Other
     ;
 
-    public static DNStoreManagerType typeOf(Map<String,String> datanucleusProps) {
+    public static DNStoreManagerType typeOf(Map<String, Object> datanucleusProps) {
 
         if(hasSecondaryDataStore(datanucleusProps)) {
             return Federated; 
@@ -85,18 +85,18 @@ enum DNStoreManagerType {
             "jdbc:db2:",
     };
 
-    private static boolean hasSecondaryDataStore(Map<String,String> datanucleusProps) {
+    private static boolean hasSecondaryDataStore(Map<String, Object> datanucleusProps) {
         final boolean hasSecondaryDataStore = datanucleusProps.keySet().stream()
                 .anyMatch(key->key.startsWith("datanucleus.datastore."));
         return hasSecondaryDataStore;
     }
 
-    private static boolean isKnownSchemaAwareStoreManagerIfNotFederated(Map<String,String> datanucleusProps) {
+    private static boolean isKnownSchemaAwareStoreManagerIfNotFederated(Map<String, Object> datanucleusProps) {
 
         // this saves some time, but also avoids the (still undiagnosed) issue that instantiating the
         // PMF can cause the ClassMetadata for the entity classes to be loaded in and cached prior to
         // registering the CreateSchemaObjectFromClassData (to invoke 'create schema' first)
-        final String connectionUrl = datanucleusProps.get("javax.jdo.option.ConnectionURL");
+        final String connectionUrl = (String) datanucleusProps.get("javax.jdo.option.ConnectionURL");
         if(connectionUrl != null) {
             for(String magic : knownSchemaAwareIfNotFederated) {
                 if (connectionUrl.startsWith(magic)) {
@@ -109,7 +109,7 @@ enum DNStoreManagerType {
     }
 
     private static DNStoreManagerType probe(
-            Map<String,String> datanucleusProps, 
+            Map<String, Object> datanucleusProps, 
             Function<StoreManager, DNStoreManagerType> categorizer) {
 
         // we create a throw-away instance of PMF so that we can probe whether DN has
diff --git a/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/persistence/DataNucleusApplicationComponents5.java b/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/persistence/DataNucleusApplicationComponents5.java
index 72f43d5..304654f 100644
--- a/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/persistence/DataNucleusApplicationComponents5.java
+++ b/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/persistence/DataNucleusApplicationComponents5.java
@@ -36,6 +36,7 @@ import org.datanucleus.metadata.MetaDataManager;
 import org.datanucleus.store.schema.SchemaAwareStoreManager;
 
 import org.apache.isis.commons.internal.base._NullSafe;
+import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.commons.internal.collections._Maps;
 import org.apache.isis.commons.internal.factory.InstanceUtil;
 import org.apache.isis.config.IsisConfiguration;
@@ -59,22 +60,29 @@ public class DataNucleusApplicationComponents5 {
 
     private final Set<String> persistableClassNameSet;
     private final IsisConfiguration configuration;
-    private final Map<String, String> datanucleusProps;
+    private final Map<String, Object> datanucleusProps;
 
     @Getter private PersistenceManagerFactory persistenceManagerFactory;
 
     public DataNucleusApplicationComponents5(
             final IsisConfiguration configuration,
-            final Map<String, String> datanucleusProps,
+            final Map<String, Object> datanucleusProps,
             final Set<String> persistableClassNameSet) {
         
         this.configuration = configuration;
         this.datanucleusProps = datanucleusProps;
         this.persistableClassNameSet = persistableClassNameSet;
 
+        
+        val pmfClass = configuration.getPersistor().getDatanucleus().getImpl()
+                .getJavax().getJdo().getPersistenceManagerFactoryClass();
+        
+        if(_Strings.isNotEmpty(pmfClass)) {
+            datanucleusProps.put("javax.jdo.PersistenceManagerFactoryClass", pmfClass);    
+        }
+        
         persistenceManagerFactory = createPmfAndSchemaIfRequired(
                 this.persistableClassNameSet, this.datanucleusProps);
-
     }
 
     /**
@@ -90,7 +98,7 @@ public class DataNucleusApplicationComponents5 {
         }
     }
 
-    static PersistenceManagerFactory newPersistenceManagerFactory(Map<String, String> datanucleusProps) {
+    static PersistenceManagerFactory newPersistenceManagerFactory(Map<String, Object> datanucleusProps) {
         try {
             // this is where DN will throw an exception if we pass it any config props it doesn't like the look of.
             // we want to fail, but let's make sure that the error is visible to help the developer
@@ -104,7 +112,7 @@ public class DataNucleusApplicationComponents5 {
     // REF: http://www.datanucleus.org/products/datanucleus/jdo/schema.html
     private PersistenceManagerFactory createPmfAndSchemaIfRequired(
             final Set<String> persistableClassNameSet, 
-            final Map<String, String> datanucleusProps) {
+            final Map<String, Object> datanucleusProps) {
 
         final DNStoreManagerType dnStoreManagerType = DNStoreManagerType.typeOf(datanucleusProps);
 
@@ -132,14 +140,14 @@ public class DataNucleusApplicationComponents5 {
             // otherwise NPEs occur later.
 
             configureAutoStart(persistableClassNameSet, datanucleusProps);
-            persistenceManagerFactory = newPersistenceManagerFactory(this.datanucleusProps);
+            persistenceManagerFactory = newPersistenceManagerFactory(datanucleusProps);
         }
 
         return persistenceManagerFactory;
 
     }
 
-    private void configureAutoCreateSchema(final Map<String, String> datanucleusProps) {
+    private void configureAutoCreateSchema(final Map<String, Object> datanucleusProps) {
         // unlike v1, we DO now use we DN's eager loading for schema (ie set to PROPERTY_SCHEMA_AUTOCREATE_ALL to true).
         //
         // the mechanism in v1 was to register a listener to create a schema just-in-time
@@ -155,7 +163,7 @@ public class DataNucleusApplicationComponents5 {
 
     private void configureAutoStart(
             final Set<String> persistableClassNameSet, 
-            final Map<String, String> datanucleusProps) {
+            final Map<String, Object> datanucleusProps) {
 
         final String persistableClassNames =
                 stream(persistableClassNameSet).collect(Collectors.joining(","));
@@ -169,7 +177,7 @@ public class DataNucleusApplicationComponents5 {
     private void createSchema(
             final PersistenceManagerFactory persistenceManagerFactory,
             final Set<String> persistableClassNameSet,
-            final Map<String, String> datanucleusProps) {
+            final Map<String, Object> datanucleusProps) {
 
         JDOPersistenceManagerFactory jdopmf = (JDOPersistenceManagerFactory) persistenceManagerFactory;
         final PersistenceNucleusContext nucleusContext = jdopmf.getNucleusContext();
@@ -187,13 +195,13 @@ public class DataNucleusApplicationComponents5 {
         schemaAwareStoreManager.createSchemaForClasses(persistableClassNameSet, asProperties(datanucleusProps));
     }
 
-    private boolean isSet(final Map<String, String> props, final String key) {
-        return Boolean.parseBoolean( props.get(key) );
+    private boolean isSet(final Map<String, Object> props, final String key) {
+        return Boolean.parseBoolean( ""+props.get(key) );
     }
 
     private void registerMetadataListener(
             final MetaDataManager metaDataManager,
-            final Map<String, String> datanucleusProps) {
+            final Map<String, Object> datanucleusProps) {
         final MetaDataListener listener = createMetaDataListener();
         if(listener == null) {
             return;
@@ -217,7 +225,7 @@ public class DataNucleusApplicationComponents5 {
     }
 
 
-    private static Properties asProperties(final Map<String, String> props) {
+    private static Properties asProperties(final Map<String, Object> props) {
         final Properties properties = new Properties();
         properties.putAll(props);
         return properties;
diff --git a/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/persistence/PersistenceSessionFactory5.java b/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/persistence/PersistenceSessionFactory5.java
index 9d2fa62..10f527b 100644
--- a/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/persistence/PersistenceSessionFactory5.java
+++ b/core/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/persistence/PersistenceSessionFactory5.java
@@ -38,9 +38,11 @@ import org.springframework.stereotype.Service;
 import org.apache.isis.applib.annotation.OrderPrecedence;
 import org.apache.isis.commons.internal.base._Blackhole;
 import org.apache.isis.commons.internal.base._Lazy;
+import org.apache.isis.commons.internal.collections._Maps;
 import org.apache.isis.config.IsisConfiguration;
 import org.apache.isis.config.beans.IsisBeanTypeRegistryHolder;
 import org.apache.isis.metamodel.context.MetaModelContext;
+import org.apache.isis.metamodel.context.MetaModelContextAware;
 import org.apache.isis.persistence.jdo.applib.fixturestate.FixturesInstalledState;
 import org.apache.isis.persistence.jdo.applib.fixturestate.FixturesInstalledStateHolder;
 import org.apache.isis.persistence.jdo.datanucleus5.datanucleus.DataNucleusSettings;
@@ -107,17 +109,21 @@ implements PersistenceSessionFactory, FixturesInstalledStateHolder {
     private DataNucleusApplicationComponents5 createDataNucleusApplicationComponents() {
 
         val dnSettings = metaModelContext.getServiceRegistry().lookupServiceElseFail(DataNucleusSettings.class);
-        val datanucleusProps = dnSettings.getAsMap(); 
+        val datanucleusProps = _Maps.<String, Object>newHashMap();
+        datanucleusProps.putAll(dnSettings.getAsMap());
+        datanucleusProps.put("isis.metamodelcontext", metaModelContext);
         
         addDataNucleusPropertiesIfRequired(datanucleusProps);
         
         val typeRegistry = isisBeanTypeRegistryHolder.getIsisBeanTypeRegistry();
         val classesToBePersisted = jdoEntityTypeRegistry.getEntityTypes(typeRegistry);
 
-        return new DataNucleusApplicationComponents5(
+        val dataNucleusApplicationComponents = new DataNucleusApplicationComponents5(
                 configuration,
                 datanucleusProps, 
                 classesToBePersisted);
+        
+        return dataNucleusApplicationComponents;
     }
 
     @Override
@@ -128,11 +134,11 @@ implements PersistenceSessionFactory, FixturesInstalledStateHolder {
                 metaModelContext.getSpecificationLoader());
     }
 
-    private static void addDataNucleusPropertiesIfRequired(Map<String, String> props) {
+    private static void addDataNucleusPropertiesIfRequired(Map<String, Object> props) {
 
         // new feature in DN 3.2.3; enables dependency injection into entities
         putIfNotPresent(props, PropertyNames.PROPERTY_OBJECT_PROVIDER_CLASS_NAME, JDOStateManagerForIsis.class.getName());
-
+        
         putIfNotPresent(props, "javax.jdo.PersistenceManagerFactoryClass", JDOPersistenceManagerFactory.class.getName());
 
         // previously we defaulted this property to "true", but that could cause the target database to be modified
@@ -143,10 +149,10 @@ implements PersistenceSessionFactory, FixturesInstalledStateHolder {
 
         putIfNotPresent(props, PropertyNames.PROPERTY_PERSISTENCE_UNIT_LOAD_CLASSES, Boolean.TRUE.toString());
 
-        String connectionFactoryName = props.get(PropertyNames.PROPERTY_CONNECTION_FACTORY_NAME);
+        String connectionFactoryName = (String) props.get(PropertyNames.PROPERTY_CONNECTION_FACTORY_NAME);
         if(connectionFactoryName != null) {
-            String connectionFactory2Name = props.get(PropertyNames.PROPERTY_CONNECTION_FACTORY2_NAME);
-            String transactionType = props.get("javax.jdo.option.TransactionType");
+            String connectionFactory2Name = (String) props.get(PropertyNames.PROPERTY_CONNECTION_FACTORY2_NAME);
+            String transactionType = (String) props.get("javax.jdo.option.TransactionType");
             // extended logging
             if(transactionType == null) {
                 log.info("found config properties to use non-JTA JNDI datasource ({})", connectionFactoryName);
@@ -182,9 +188,10 @@ implements PersistenceSessionFactory, FixturesInstalledStateHolder {
     }
 
     private static void putIfNotPresent(
-            final Map<String, String> props,
+            Map<String, Object> props,
             String key,
             String value) {
+        
         if(!props.containsKey(key)) {
             props.put(key, value);
         }