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 2019/02/13 09:02:46 UTC

[isis] branch 2033-IoC updated: ISIS-2033: refactoring FixtureScript's installed state

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

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


The following commit(s) were added to refs/heads/2033-IoC by this push:
     new 8e62eec  ISIS-2033: refactoring FixtureScript's installed state
8e62eec is described below

commit 8e62eec634153d6021318a4fec68e2f620219410
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Feb 13 10:02:39 2019 +0100

    ISIS-2033: refactoring FixtureScript's installed state
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-2033
---
 .../apache/isis/applib/fixtures/FixtureType.java   | 14 +++-
 .../system/persistence/PersistenceSession4.java    | 85 ++++++++++-----------
 .../persistence/PersistenceSessionFactory4.java    | 58 ++++++---------
 .../system/persistence/PersistenceSession5.java    | 86 ++++++++++------------
 .../persistence/PersistenceSessionFactory5.java    | 54 ++++++--------
 .../fixtures/FixturesInstallerAbstract.java        |  5 +-
 .../fixtures/FixturesInstallerDelegate.java        | 36 +++++----
 .../FixturesInstallerFromConfiguration.java        |  5 +-
 ...talledFlag.java => FixturesInstalledState.java} | 42 ++++++++---
 ...Flag.java => FixturesInstalledStateHolder.java} | 13 ++--
 .../context/session/ManagedObjectContext.java      |  5 +-
 .../context/session/ManagedObjectContextBase.java  |  8 ++
 .../context/session/ManagedObjectPersistence.java  | 11 +++
 .../system/persistence/PersistenceSession.java     | 54 ++++++--------
 .../system/persistence/PersistenceSessionBase.java | 21 +++---
 .../core/runtime/system/session/IsisSession.java   |  2 +
 .../system/session/IsisSessionFactoryDefault.java  |  4 +-
 .../server/resources/DomainResourceHelper.java     |  6 ++
 18 files changed, 256 insertions(+), 253 deletions(-)

diff --git a/core/applib/src/main/java/org/apache/isis/applib/fixtures/FixtureType.java b/core/applib/src/main/java/org/apache/isis/applib/fixtures/FixtureType.java
index 5d19aa5..febabc5 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/fixtures/FixtureType.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/fixtures/FixtureType.java
@@ -26,6 +26,7 @@ package org.apache.isis.applib.fixtures;
  * @see InstallableFixture#getType()
  */
 public enum FixtureType {
+	
     /**
      * A fixture that installs data (either reference data or operational data)
      * into an object store.
@@ -38,8 +39,9 @@ public enum FixtureType {
      * time booted to initially seed them).
      */
     DOMAIN_OBJECTS,
+    
     /**
-     * A fixture that does not installs data into the object store.
+     * A fixture that does not install data into the object store.
      *
      * <p>
      * Fixtures of this type are always installed. Typical examples are:
@@ -50,5 +52,13 @@ public enum FixtureType {
      * ).
      * </ul>
      */
-    OTHER;
+    OTHER
+    
+    ;
+	
+	public boolean isAlwaysInstall() {
+		return this == OTHER;
+	}
+	
+	
 }
\ No newline at end of file
diff --git a/core/plugins/jdo-datanucleus-4/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession4.java b/core/plugins/jdo-datanucleus-4/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession4.java
index 9eed184..ef588e4 100644
--- a/core/plugins/jdo-datanucleus-4/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession4.java
+++ b/core/plugins/jdo-datanucleus-4/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession4.java
@@ -45,6 +45,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import lombok.val;
+import lombok.extern.slf4j.Slf4j;
 
 import org.apache.isis.applib.query.Query;
 import org.apache.isis.applib.services.command.Command;
@@ -78,7 +79,8 @@ import org.apache.isis.core.metamodel.spec.ManagedObjectState;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.plugins.ioc.RequestContextHandle;
 import org.apache.isis.core.plugins.ioc.RequestContextService;
-import org.apache.isis.core.runtime.persistence.FixturesInstalledFlag;
+import org.apache.isis.core.runtime.persistence.FixturesInstalledState;
+import org.apache.isis.core.runtime.persistence.FixturesInstalledStateHolder;
 import org.apache.isis.core.runtime.persistence.NotPersistableException;
 import org.apache.isis.core.runtime.persistence.ObjectNotFoundException;
 import org.apache.isis.core.runtime.persistence.PojoRefreshException;
@@ -107,6 +109,7 @@ import org.apache.isis.objectstore.jdo.datanucleus.persistence.spi.JdoObjectIdSe
  * and maintains an identity map of {@link ObjectAdapter adapter}s and {@link Oid
  * identities} for each and every POJO that is being used by the framework.
  */
+@Slf4j
 public class PersistenceSession4 extends PersistenceSessionBase
 implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
 
@@ -120,7 +123,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
     public PersistenceSession4(
             final AuthenticationSession authenticationSession,
             final PersistenceManagerFactory jdoPersistenceManagerFactory,
-            final FixturesInstalledFlag fixturesInstalledFlag) {
+            final FixturesInstalledStateHolder fixturesInstalledFlag) {
 
         super(authenticationSession, jdoPersistenceManagerFactory, fixturesInstalledFlag);
     }
@@ -137,8 +140,8 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
         
         openedAtSystemNanos = System.nanoTime();
 
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("opening {}", this);
+        if (log.isDebugEnabled()) {
+            log.debug("opening {}", this);
         }
         
         // this handle needs to be closed when the request-scope's life-cycle ends
@@ -249,7 +252,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
             }
         } catch(final Throwable ex) {
             // ignore
-            LOG.error("close: failed to end transaction; continuing to avoid memory leakage");
+            log.error("close: failed to end transaction; continuing to avoid memory leakage");
         }
 
         // tell the proxy of all request-scoped services to invoke @PreDestroy
@@ -263,7 +266,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
             persistenceManager.close();
         } catch(final Throwable ex) {
             // ignore
-            LOG.error(
+            log.error(
                     "close: failed to close JDO persistenceManager; continuing to avoid memory leakage");
         }
 
@@ -355,14 +358,14 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
      *             if the criteria is not support by this persistor
      */
     private <T> ObjectAdapter findInstancesInTransaction(final Query<T> query, final QueryCardinality cardinality) {
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("findInstances using (applib) Query: {}", query);
+        if (log.isDebugEnabled()) {
+            log.debug("findInstances using (applib) Query: {}", query);
         }
 
         // TODO: unify PersistenceQuery and PersistenceQueryProcessor
         final PersistenceQuery persistenceQuery = createPersistenceQueryFor(query, cardinality);
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("maps to (core runtime) PersistenceQuery: {}", persistenceQuery);
+        if (log.isDebugEnabled()) {
+            log.debug("maps to (core runtime) PersistenceQuery: {}", persistenceQuery);
         }
 
         final PersistenceQueryProcessor<? extends PersistenceQuery> processor = lookupProcessorFor(persistenceQuery);
@@ -411,35 +414,15 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
 
     // -- fixture installation
 
-    /**
-     * Determine if the object store has been initialized with its set of start
-     * up objects.
-     *
-     * <p>
-     * This method is called only once after the init has been called. If this flag
-     * returns <code>false</code> the framework will run the fixtures to
-     * initialise the persistor.
-     *
-     * <p>
-     * Returns the cached value of {@link #isFixturesInstalled()
-     * whether fixtures are installed} from the
-     * {@link PersistenceSessionFactory}.
-     * <p>
-     * This caching is important because if we've determined, for a given run,
-     * that fixtures are not installed, then we don't want to change our mind by
-     * asking the object store again in another session.
-     *
-     * @see FixturesInstalledFlag
-     */
     @Override
-    public boolean isFixturesInstalled() {
-        if (fixturesInstalledFlag.isFixturesInstalled() == null) {
-            fixturesInstalledFlag.setFixturesInstalled(objectStoreIsFixturesInstalled());
+    public FixturesInstalledState getFixturesInstalledState() {
+        if (fixturesInstalledStateHolder.getFixturesInstalledState() == null) {
+        	val initialStateFromConfig = initialStateFromConfig();
+            fixturesInstalledStateHolder.setFixturesInstalledState(initialStateFromConfig);
         }
-        return fixturesInstalledFlag.isFixturesInstalled();
+        return fixturesInstalledStateHolder.getFixturesInstalledState();
     }
 
-
     /**
      * Determine if the object store has been initialized with its set of start
      * up objects.
@@ -455,10 +438,16 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
      * By default this is not expected to be there, but utilities can add in on
      * the fly during bootstrapping if required.
      */
-    private boolean objectStoreIsFixturesInstalled() {
-        final boolean installFixtures = configuration.getBoolean(INSTALL_FIXTURES_KEY, INSTALL_FIXTURES_DEFAULT);
-        LOG.info("isFixturesInstalled: {} = {}", INSTALL_FIXTURES_KEY, installFixtures);
-        return !installFixtures;
+    private FixturesInstalledState initialStateFromConfig() {
+        val installFixtures = configuration.getBoolean(INSTALL_FIXTURES_KEY, INSTALL_FIXTURES_DEFAULT);
+        log.info("isFixturesInstalled: {} = {}", INSTALL_FIXTURES_KEY, installFixtures);
+        
+        val objectStoreIsFixturesInstalled = !installFixtures;
+        val initialStateFromConfig = objectStoreIsFixturesInstalled
+    			? FixturesInstalledState.Installed
+    					: FixturesInstalledState.not_Installed;
+        
+        return initialStateFromConfig;
     }
 
     // -- FETCHING
@@ -466,7 +455,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
     @Override
     public Object fetchPersistentPojo(final RootOid rootOid) {
         Objects.requireNonNull(rootOid);
-        LOG.debug("getObject; oid={}", rootOid);
+        log.debug("getObject; oid={}", rootOid);
         
         Object result;
         try {
@@ -630,7 +619,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
         if (alreadyPersistedOrNotPersistable(adapter)) {
             return;
         }
-        LOG.debug("persist {}", adapter);
+        log.debug("persist {}", adapter);
 
         // previously we called the PersistingCallback here.
         // this is now done in the JDO framework synchronizer.
@@ -676,7 +665,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
         if (spec.isParented()) {
             return;
         }
-        LOG.debug("destroyObject {}", adapter);
+        log.debug("destroyObject {}", adapter);
         transactionManager.executeWithinTransaction(()->{
                 final DestroyObjectCommand command = newDestroyObjectCommand(adapter);
                 transactionManager.addCommand(command);
@@ -707,7 +696,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
     private CreateObjectCommand newCreateObjectCommand(final ObjectAdapter adapter) {
         ensureOpened();
 
-        LOG.debug("create object - creating command for: {}", adapter);
+        log.debug("create object - creating command for: {}", adapter);
         if (adapter.isRepresentingPersistent()) {
             throw new IllegalArgumentException("Adapter is persistent; adapter: " + adapter);
         }
@@ -717,7 +706,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
     private DestroyObjectCommand newDestroyObjectCommand(final ObjectAdapter adapter) {
         ensureOpened();
 
-        LOG.debug("destroy object - creating command for: {}", adapter);
+        log.debug("destroy object - creating command for: {}", adapter);
         if (!adapter.isRepresentingPersistent()) {
             throw new IllegalArgumentException("Adapter is not persistent; adapter: " + adapter);
         }
@@ -934,16 +923,16 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
     // -- HELPER
     
     private void debugLogNotPersistentIgnoring(Object domainObject) {
-        if (LOG.isDebugEnabled() && domainObject!=null) {
+        if (log.isDebugEnabled() && domainObject!=null) {
             final Oid oid = oidFor(domainObject);
-            LOG.debug("; oid={} not persistent - ignoring", oid.enString());
+            log.debug("; oid={} not persistent - ignoring", oid.enString());
         }     
     }
 
     private void debugLogRefreshImmediately(Object domainObject) {
-        if (LOG.isDebugEnabled()) {
+        if (log.isDebugEnabled()) {
             final Oid oid = oidFor(domainObject);
-            LOG.debug("refresh immediately; oid={}", oid.enString());
+            log.debug("refresh immediately; oid={}", oid.enString());
         }
     }
 
diff --git a/core/plugins/jdo-datanucleus-4/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactory4.java b/core/plugins/jdo-datanucleus-4/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactory4.java
index 3358deb..e60f694 100644
--- a/core/plugins/jdo-datanucleus-4/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactory4.java
+++ b/core/plugins/jdo-datanucleus-4/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactory4.java
@@ -26,21 +26,23 @@ import java.util.Set;
 import javax.enterprise.inject.Vetoed;
 import javax.jdo.PersistenceManagerFactory;
 
-import org.datanucleus.PropertyNames;
-import org.datanucleus.api.jdo.JDOPersistenceManagerFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.services.inject.ServiceInjector;
 import org.apache.isis.commons.internal.base._Lazy;
 import org.apache.isis.config.IsisConfiguration;
 import org.apache.isis.config.internal._Config;
 import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
-import org.apache.isis.core.runtime.persistence.FixturesInstalledFlag;
+import org.apache.isis.core.runtime.persistence.FixturesInstalledState;
+import org.apache.isis.core.runtime.persistence.FixturesInstalledStateHolder;
 import org.apache.isis.core.security.authentication.AuthenticationSession;
 import org.apache.isis.objectstore.jdo.datanucleus.JDOStateManagerForIsis;
 import org.apache.isis.objectstore.jdo.service.RegisterEntities;
+import org.datanucleus.PropertyNames;
+import org.datanucleus.api.jdo.JDOPersistenceManagerFactory;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
 
 /**
  *
@@ -51,11 +53,9 @@ import org.apache.isis.objectstore.jdo.service.RegisterEntities;
  * must be annotated using {@link Programmatic}.
  * </p>
  */
-@Vetoed // has a producer
+@Slf4j @Vetoed // has a producer
 public class PersistenceSessionFactory4 implements
-PersistenceSessionFactory, FixturesInstalledFlag {
-
-    private static final Logger LOG = LoggerFactory.getLogger(PersistenceSessionFactory4.class);
+PersistenceSessionFactory, FixturesInstalledStateHolder {
 
     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
@@ -65,6 +65,10 @@ PersistenceSessionFactory, FixturesInstalledFlag {
             _Lazy.threadSafe(this::createDataNucleusApplicationComponents);
 
     private IsisConfiguration configuration;
+    
+    @Getter(onMethod=@__({@Override})) 
+    @Setter(onMethod=@__({@Override})) 
+    FixturesInstalledState fixturesInstalledState;
 
     @Programmatic
     @Override
@@ -106,10 +110,6 @@ PersistenceSessionFactory, FixturesInstalledFlag {
         DataNucleusApplicationComponents4.catalogNamedQueries(classesToBePersisted, specificationLoader);
     }
 
-    private boolean shouldCreate(final DataNucleusApplicationComponents4 applicationComponents) {
-        return applicationComponents == null || applicationComponents.isStale();
-    }
-
     private static void addDataNucleusPropertiesIfRequired(
             final Map<String, String> props) {
 
@@ -132,24 +132,24 @@ PersistenceSessionFactory, FixturesInstalledFlag {
             String transactionType = props.get("javax.jdo.option.TransactionType");
             // extended logging
             if(transactionType == null) {
-                LOG.info("found config properties to use non-JTA JNDI datasource ({})", connectionFactoryName);
+                log.info("found config properties to use non-JTA JNDI datasource ({})", connectionFactoryName);
                 if(connectionFactory2Name != null) {
-                    LOG.warn("found config properties to use non-JTA JNDI datasource ({}); second '-nontx' JNDI datasource also configured but will not be used ({})", connectionFactoryName, connectionFactory2Name);
+                	log.warn("found config properties to use non-JTA JNDI datasource ({}); second '-nontx' JNDI datasource also configured but will not be used ({})", connectionFactoryName, connectionFactory2Name);
                 }
             } else {
-                LOG.info("found config properties to use JTA JNDI datasource ({})", connectionFactoryName);
+            	log.info("found config properties to use JTA JNDI datasource ({})", connectionFactoryName);
             }
             if(connectionFactory2Name == null) {
                 // JDO/DN itself will (probably) throw an exception
-                LOG.error("found config properties to use JTA JNDI datasource ({}) but config properties for second '-nontx' JNDI datasource were *not* found", connectionFactoryName);
+            	log.error("found config properties to use JTA JNDI datasource ({}) but config properties for second '-nontx' JNDI datasource were *not* found", connectionFactoryName);
             } else {
-                LOG.info("... and config properties for second '-nontx' JNDI datasource also found; {}", connectionFactory2Name);
+            	log.info("... and config properties for second '-nontx' JNDI datasource also found; {}", connectionFactory2Name);
             }
             // nothing further to do
             return;
         } else {
             // use JDBC connection properties; put if not present
-            LOG.info("did *not* find config properties to use JNDI datasource; will use JDBC");
+        	log.info("did *not* find config properties to use JNDI datasource; will use JDBC");
 
             putIfNotPresent(props, "javax.jdo.option.ConnectionDriverName", "org.hsqldb.jdbcDriver");
             putIfNotPresent(props, "javax.jdo.option.ConnectionURL", "jdbc:hsqldb:mem:test");
@@ -191,7 +191,7 @@ PersistenceSessionFactory, FixturesInstalledFlag {
         Objects.requireNonNull(applicationComponents,
                 () -> "PersistenceSession5 requires initialization. " + this.hashCode());
         
-        final FixturesInstalledFlag fixturesInstalledFlag = this;
+        final FixturesInstalledStateHolder fixturesInstalledStateHolder = this;
         
         //[ahuber] if stale force recreate
         guardAgainstStaleState();
@@ -201,21 +201,7 @@ PersistenceSessionFactory, FixturesInstalledFlag {
 
         return new PersistenceSession4(
                 authenticationSession, persistenceManagerFactory,
-                fixturesInstalledFlag);
-    }
-
-    private Boolean fixturesInstalled;
-
-    @Programmatic
-    @Override
-    public Boolean isFixturesInstalled() {
-        return fixturesInstalled;
-    }
-
-    @Programmatic
-    @Override
-    public void setFixturesInstalled(final Boolean fixturesInstalled) {
-        this.fixturesInstalled = fixturesInstalled;
+                fixturesInstalledStateHolder);
     }
 
     // [ahuber] JRebel support, not tested at all
diff --git a/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession5.java b/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession5.java
index 617e4b4..e141112 100644
--- a/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession5.java
+++ b/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession5.java
@@ -69,7 +69,8 @@ import org.apache.isis.core.metamodel.spec.ManagedObjectState;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.plugins.ioc.RequestContextHandle;
 import org.apache.isis.core.plugins.ioc.RequestContextService;
-import org.apache.isis.core.runtime.persistence.FixturesInstalledFlag;
+import org.apache.isis.core.runtime.persistence.FixturesInstalledState;
+import org.apache.isis.core.runtime.persistence.FixturesInstalledStateHolder;
 import org.apache.isis.core.runtime.persistence.NotPersistableException;
 import org.apache.isis.core.runtime.persistence.ObjectNotFoundException;
 import org.apache.isis.core.runtime.persistence.PojoRefreshException;
@@ -96,13 +97,14 @@ import org.datanucleus.exceptions.NucleusObjectNotFoundException;
 import org.datanucleus.identity.DatastoreIdImpl;
 
 import lombok.val;
+import lombok.extern.slf4j.Slf4j;
 
 /**
  * A wrapper around the JDO {@link PersistenceManager}, which also manages concurrency
  * and maintains an identity map of {@link ObjectAdapter adapter}s and {@link Oid
  * identities} for each and every POJO that is being used by the framework.
  */
-//@Slf4j
+@Slf4j
 public class PersistenceSession5 extends PersistenceSessionBase
 implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
 
@@ -116,7 +118,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
     public PersistenceSession5(
             final AuthenticationSession authenticationSession,
             final PersistenceManagerFactory jdoPersistenceManagerFactory,
-            final FixturesInstalledFlag fixturesInstalledFlag) {
+            final FixturesInstalledStateHolder fixturesInstalledFlag) {
 
         super(authenticationSession, jdoPersistenceManagerFactory, fixturesInstalledFlag);
     }
@@ -133,8 +135,8 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
         
         openedAtSystemNanos = System.nanoTime();
 
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("opening {}", this);
+        if (log.isDebugEnabled()) {
+            log.debug("opening {}", this);
         }
         
         // this handle needs to be closed when the request-scope's life-cycle ends
@@ -245,7 +247,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
             }
         } catch(final Throwable ex) {
             // ignore
-            LOG.error("close: failed to end transaction; continuing to avoid memory leakage");
+            log.error("close: failed to end transaction; continuing to avoid memory leakage");
         }
 
         // tell the proxy of all request-scoped services to invoke @PreDestroy
@@ -259,7 +261,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
             persistenceManager.close();
         } catch(final Throwable ex) {
             // ignore
-            LOG.error(
+            log.error(
                     "close: failed to close JDO persistenceManager; continuing to avoid memory leakage");
         }
 
@@ -351,14 +353,14 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
      *             if the criteria is not support by this persistor
      */
     private <T> ObjectAdapter findInstancesInTransaction(final Query<T> query, final QueryCardinality cardinality) {
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("findInstances using (applib) Query: {}", query);
+        if (log.isDebugEnabled()) {
+            log.debug("findInstances using (applib) Query: {}", query);
         }
 
         // TODO: unify PersistenceQuery and PersistenceQueryProcessor
         final PersistenceQuery persistenceQuery = createPersistenceQueryFor(query, cardinality);
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("maps to (core runtime) PersistenceQuery: {}", persistenceQuery);
+        if (log.isDebugEnabled()) {
+            log.debug("maps to (core runtime) PersistenceQuery: {}", persistenceQuery);
         }
 
         final PersistenceQueryProcessor<? extends PersistenceQuery> processor = lookupProcessorFor(persistenceQuery);
@@ -407,35 +409,15 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
 
     // -- fixture installation
 
-    /**
-     * Determine if the object store has been initialized with its set of start
-     * up objects.
-     *
-     * <p>
-     * This method is called only once after the init has been called. If this flag
-     * returns <code>false</code> the framework will run the fixtures to
-     * initialise the persistor.
-     *
-     * <p>
-     * Returns the cached value of {@link #isFixturesInstalled()
-     * whether fixtures are installed} from the
-     * {@link PersistenceSessionFactory}.
-     * <p>
-     * This caching is important because if we've determined, for a given run,
-     * that fixtures are not installed, then we don't want to change our mind by
-     * asking the object store again in another session.
-     *
-     * @see FixturesInstalledFlag
-     */
     @Override
-    public boolean isFixturesInstalled() {
-        if (fixturesInstalledFlag.isFixturesInstalled() == null) {
-            fixturesInstalledFlag.setFixturesInstalled(objectStoreIsFixturesInstalled());
+    public FixturesInstalledState getFixturesInstalledState() {
+        if (fixturesInstalledStateHolder.getFixturesInstalledState() == null) {
+        	val initialStateFromConfig = initialStateFromConfig();
+            fixturesInstalledStateHolder.setFixturesInstalledState(initialStateFromConfig);
         }
-        return fixturesInstalledFlag.isFixturesInstalled();
+        return fixturesInstalledStateHolder.getFixturesInstalledState();
     }
 
-
     /**
      * Determine if the object store has been initialized with its set of start
      * up objects.
@@ -451,10 +433,16 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
      * By default this is not expected to be there, but utilities can add in on
      * the fly during bootstrapping if required.
      */
-    private boolean objectStoreIsFixturesInstalled() {
-        final boolean installFixtures = configuration.getBoolean(INSTALL_FIXTURES_KEY, INSTALL_FIXTURES_DEFAULT);
-        LOG.info("isFixturesInstalled: {} = {}", INSTALL_FIXTURES_KEY, installFixtures);
-        return !installFixtures;
+    private FixturesInstalledState initialStateFromConfig() {
+        val installFixtures = configuration.getBoolean(INSTALL_FIXTURES_KEY, INSTALL_FIXTURES_DEFAULT);
+        log.info("isFixturesInstalled: {} = {}", INSTALL_FIXTURES_KEY, installFixtures);
+        
+        val objectStoreIsFixturesInstalled = !installFixtures;
+        val initialStateFromConfig = objectStoreIsFixturesInstalled
+    			? FixturesInstalledState.Installed
+    					: FixturesInstalledState.not_Installed;
+        
+        return initialStateFromConfig;
     }
 
     // -- FETCHING
@@ -462,7 +450,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
     @Override
     public Object fetchPersistentPojo(final RootOid rootOid) {
         Objects.requireNonNull(rootOid);
-        LOG.debug("getObject; oid={}", rootOid);
+        log.debug("getObject; oid={}", rootOid);
         
         Object result;
         try {
@@ -626,7 +614,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
         if (alreadyPersistedOrNotPersistable(adapter)) {
             return;
         }
-        LOG.debug("persist {}", adapter);
+        log.debug("persist {}", adapter);
 
         // previously we called the PersistingCallback here.
         // this is now done in the JDO framework synchronizer.
@@ -672,7 +660,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
         if (spec.isParented()) {
             return;
         }
-        LOG.debug("destroyObject {}", adapter);
+        log.debug("destroyObject {}", adapter);
         transactionManager.executeWithinTransaction(()->{
                 final DestroyObjectCommand command = newDestroyObjectCommand(adapter);
                 transactionManager.addCommand(command);
@@ -703,7 +691,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
     private CreateObjectCommand newCreateObjectCommand(final ObjectAdapter adapter) {
         ensureOpened();
 
-        LOG.debug("create object - creating command for: {}", adapter);
+        log.debug("create object - creating command for: {}", adapter);
         if (adapter.isRepresentingPersistent()) {
             throw new IllegalArgumentException("Adapter is persistent; adapter: " + adapter);
         }
@@ -713,7 +701,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
     private DestroyObjectCommand newDestroyObjectCommand(final ObjectAdapter adapter) {
         ensureOpened();
 
-        LOG.debug("destroy object - creating command for: {}", adapter);
+        log.debug("destroy object - creating command for: {}", adapter);
         if (!adapter.isRepresentingPersistent()) {
             throw new IllegalArgumentException("Adapter is not persistent; adapter: " + adapter);
         }
@@ -930,16 +918,16 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
     // -- HELPER
     
     private void debugLogNotPersistentIgnoring(Object domainObject) {
-        if (LOG.isDebugEnabled() && domainObject!=null) {
+        if (log.isDebugEnabled() && domainObject!=null) {
             final Oid oid = oidFor(domainObject);
-            LOG.debug("; oid={} not persistent - ignoring", oid.enString());
+            log.debug("; oid={} not persistent - ignoring", oid.enString());
         }     
     }
 
     private void debugLogRefreshImmediately(Object domainObject) {
-        if (LOG.isDebugEnabled()) {
+        if (log.isDebugEnabled()) {
             final Oid oid = oidFor(domainObject);
-            LOG.debug("refresh immediately; oid={}", oid.enString());
+            log.debug("refresh immediately; oid={}", oid.enString());
         }
     }
 
diff --git a/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactory5.java b/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactory5.java
index 5f9f2f5..50baa74 100644
--- a/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactory5.java
+++ b/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactory5.java
@@ -32,14 +32,17 @@ import org.apache.isis.commons.internal.base._Lazy;
 import org.apache.isis.config.IsisConfiguration;
 import org.apache.isis.config.internal._Config;
 import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
-import org.apache.isis.core.runtime.persistence.FixturesInstalledFlag;
+import org.apache.isis.core.runtime.persistence.FixturesInstalledState;
+import org.apache.isis.core.runtime.persistence.FixturesInstalledStateHolder;
 import org.apache.isis.core.security.authentication.AuthenticationSession;
 import org.apache.isis.objectstore.jdo.datanucleus.JDOStateManagerForIsis;
 import org.apache.isis.objectstore.jdo.service.RegisterEntities;
 import org.datanucleus.PropertyNames;
 import org.datanucleus.api.jdo.JDOPersistenceManagerFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
 
 /**
  *
@@ -50,11 +53,9 @@ import org.slf4j.LoggerFactory;
  * must be annotated using {@link Programmatic}.
  * </p>
  */
-@Vetoed // has a producer
+@Slf4j @Vetoed // has a producer
 public class PersistenceSessionFactory5
-implements PersistenceSessionFactory, FixturesInstalledFlag {
-
-    private static final Logger LOG = LoggerFactory.getLogger(PersistenceSessionFactory5.class);
+implements PersistenceSessionFactory, FixturesInstalledStateHolder {
 
     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
@@ -65,6 +66,10 @@ implements PersistenceSessionFactory, FixturesInstalledFlag {
 
     private IsisConfiguration configuration;
     
+    @Getter(onMethod=@__({@Override})) 
+    @Setter(onMethod=@__({@Override})) 
+    FixturesInstalledState fixturesInstalledState;
+    
     @Programmatic
     @Override
     public void init() {
@@ -105,10 +110,6 @@ implements PersistenceSessionFactory, FixturesInstalledFlag {
         DataNucleusApplicationComponents5.catalogNamedQueries(classesToBePersisted, specificationLoader);
     }
 
-    private boolean shouldCreate(final DataNucleusApplicationComponents5 applicationComponents) {
-        return applicationComponents == null || applicationComponents.isStale();
-    }
-
     private static void addDataNucleusPropertiesIfRequired(
             final Map<String, String> props) {
 
@@ -131,24 +132,24 @@ implements PersistenceSessionFactory, FixturesInstalledFlag {
             String transactionType = props.get("javax.jdo.option.TransactionType");
             // extended logging
             if(transactionType == null) {
-                LOG.info("found config properties to use non-JTA JNDI datasource ({})", connectionFactoryName);
+                log.info("found config properties to use non-JTA JNDI datasource ({})", connectionFactoryName);
                 if(connectionFactory2Name != null) {
-                    LOG.warn("found config properties to use non-JTA JNDI datasource ({}); second '-nontx' JNDI datasource also configured but will not be used ({})", connectionFactoryName, connectionFactory2Name);
+                	log.warn("found config properties to use non-JTA JNDI datasource ({}); second '-nontx' JNDI datasource also configured but will not be used ({})", connectionFactoryName, connectionFactory2Name);
                 }
             } else {
-                LOG.info("found config properties to use JTA JNDI datasource ({})", connectionFactoryName);
+            	log.info("found config properties to use JTA JNDI datasource ({})", connectionFactoryName);
             }
             if(connectionFactory2Name == null) {
                 // JDO/DN itself will (probably) throw an exception
-                LOG.error("found config properties to use JTA JNDI datasource ({}) but config properties for second '-nontx' JNDI datasource were *not* found", connectionFactoryName);
+            	log.error("found config properties to use JTA JNDI datasource ({}) but config properties for second '-nontx' JNDI datasource were *not* found", connectionFactoryName);
             } else {
-                LOG.info("... and config properties for second '-nontx' JNDI datasource also found; {}", connectionFactory2Name);
+            	log.info("... and config properties for second '-nontx' JNDI datasource also found; {}", connectionFactory2Name);
             }
             // nothing further to do
             return;
         } else {
             // use JDBC connection properties; put if not present
-            LOG.info("did *not* find config properties to use JNDI datasource; will use JDBC");
+        	log.info("did *not* find config properties to use JNDI datasource; will use JDBC");
 
             putIfNotPresent(props, "javax.jdo.option.ConnectionDriverName", "org.hsqldb.jdbcDriver");
             putIfNotPresent(props, "javax.jdo.option.ConnectionURL", "jdbc:hsqldb:mem:test");
@@ -190,7 +191,7 @@ implements PersistenceSessionFactory, FixturesInstalledFlag {
         Objects.requireNonNull(applicationComponents.get(),
                 () -> "PersistenceSession5 requires initialization. "+this.hashCode());
         
-        final FixturesInstalledFlag fixturesInstalledFlag = this;
+        final FixturesInstalledStateHolder fixturesInstalledStateHolder = this;
         
         //[ahuber] if stale force recreate
         guardAgainstStaleState();
@@ -200,22 +201,9 @@ implements PersistenceSessionFactory, FixturesInstalledFlag {
 
         return new PersistenceSession5(
                 authenticationSession, persistenceManagerFactory,
-                fixturesInstalledFlag);
+                fixturesInstalledStateHolder);
     }
 
-    private Boolean fixturesInstalled;
-
-    @Programmatic
-    @Override
-    public Boolean isFixturesInstalled() {
-        return fixturesInstalled;
-    }
-
-    @Programmatic
-    @Override
-    public void setFixturesInstalled(final Boolean fixturesInstalled) {
-        this.fixturesInstalled = fixturesInstalled;
-    }
     
     // [ahuber] JRebel support, not tested at all
     private void guardAgainstStaleState() {
@@ -230,4 +218,6 @@ implements PersistenceSessionFactory, FixturesInstalledFlag {
     }
 
 
+
+
 }
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/fixtures/FixturesInstallerAbstract.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/fixtures/FixturesInstallerAbstract.java
index 2cca704..05ac872 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/fixtures/FixturesInstallerAbstract.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/fixtures/FixturesInstallerAbstract.java
@@ -24,15 +24,14 @@ import java.util.List;
 
 import org.apache.isis.config.IsisConfiguration;
 import org.apache.isis.core.runtime.system.context.IsisContext;
-import org.apache.isis.core.runtime.system.session.IsisSessionFactory;
 
 public abstract class FixturesInstallerAbstract {
 
     private final FixturesInstallerDelegate delegate;
     protected final IsisConfiguration configuration;
 
-    public FixturesInstallerAbstract(final IsisSessionFactory isisSessionFactory) {
-        delegate = new FixturesInstallerDelegate(isisSessionFactory);
+    public FixturesInstallerAbstract() {
+        delegate = new FixturesInstallerDelegate();
         configuration = IsisContext.getConfiguration();
     }
 
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/fixtures/FixturesInstallerDelegate.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/fixtures/FixturesInstallerDelegate.java
index 2cfa1de..af81167 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/fixtures/FixturesInstallerDelegate.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/fixtures/FixturesInstallerDelegate.java
@@ -32,8 +32,9 @@ import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.config.IsisConfiguration;
 import org.apache.isis.config.internal._Config;
 import org.apache.isis.core.commons.lang.ObjectExtensions;
+import org.apache.isis.core.runtime.system.context.IsisContext;
 import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
-import org.apache.isis.core.runtime.system.session.IsisSessionFactory;
+import org.apache.isis.core.runtime.system.session.IsisSession;
 import org.apache.isis.core.runtime.system.transaction.IsisTransactionManager;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -44,10 +45,8 @@ public class FixturesInstallerDelegate {
 
     // -- Constructor, fields
 
-    private final IsisSessionFactory isisSessionFactory;
-
-    public FixturesInstallerDelegate(final IsisSessionFactory isisSessionFactory) {
-        this.isisSessionFactory = isisSessionFactory;
+    public FixturesInstallerDelegate() {
+        
     }
 
     private final List<Object> fixtures = _Lists.newArrayList();
@@ -74,8 +73,6 @@ public class FixturesInstallerDelegate {
         return Collections.unmodifiableList(fixtures);
     }
 
-
-
     // -- installFixtures
 
     /**
@@ -96,7 +93,7 @@ public class FixturesInstallerDelegate {
             if(fireEvents) {
                 eventBusService.post(new FixturesInstallingEvent(this));
             }
-            installFixtures(Collections.unmodifiableList(fixtures));
+            installFixtures(getFixtures());
         } finally {
             if(fireEvents) {
                 eventBusService.post(new FixturesInstalledEvent(this));
@@ -115,7 +112,7 @@ public class FixturesInstallerDelegate {
     }
 
     private void installFixtureInTransaction(final Object fixture) {
-        getServicesInjector().injectServicesInto(fixture);
+        getServiceInjector().injectServicesInto(fixture);
 
         // now, install the fixture itself
         try {
@@ -136,7 +133,7 @@ public class FixturesInstallerDelegate {
     }
 
     private void installFixture(final Object fixture) {
-        isisSessionFactory.getServiceInjector().injectServicesInto(fixture);
+        getServiceInjector().injectServicesInto(fixture);
 
         if (fixture instanceof InstallableFixture) {
             final InstallableFixture installableFixture = (InstallableFixture) fixture;
@@ -149,27 +146,28 @@ public class FixturesInstallerDelegate {
 
     private boolean shouldInstallFixture(final InstallableFixture installableFixture) {
         final FixtureType fixtureType = installableFixture.getType();
-        if (fixtureType == FixtureType.DOMAIN_OBJECTS) {
-            return !isisSessionFactory.getCurrentSession().getPersistenceSession().isFixturesInstalled();
+        
+        if(fixtureType.isAlwaysInstall()) {
+        	return true;
         }
-
-        // fixtureType is OTHER; always install.
-        return true;
+        
+        //TODO [2033] what, why? only install if already installed?
+        return IsisSession.currentIfAny().getFixturesInstalledState().isInstalled();
     }
 
 
     // -- dependencies (derived)
 
-    private ServiceInjector getServicesInjector() {
-        return isisSessionFactory.getServiceInjector();
+    private ServiceInjector getServiceInjector() {
+        return IsisContext.getServiceInjector();
     }
 
     private EventBusService getEventBusService() {
-        return getServicesInjector().lookupServiceElseFail(EventBusService.class);
+        return IsisContext.getServiceRegistry().lookupServiceElseFail(EventBusService.class);
     }
 
     private PersistenceSession getPersistenceSession() {
-        return isisSessionFactory.getCurrentSession().getPersistenceSession();
+        return IsisSession.currentIfAny().getPersistenceSession();
     }
 
     private IsisTransactionManager getTransactionManager() {
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/fixtures/FixturesInstallerFromConfiguration.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/fixtures/FixturesInstallerFromConfiguration.java
index 54d847b..2f2ae2a 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/fixtures/FixturesInstallerFromConfiguration.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/fixtures/FixturesInstallerFromConfiguration.java
@@ -24,7 +24,6 @@ import java.util.List;
 import org.apache.isis.applib.fixturescripts.FixtureScript;
 import org.apache.isis.core.commons.exceptions.IsisException;
 import org.apache.isis.core.commons.factory.InstanceUtil;
-import org.apache.isis.core.runtime.system.session.IsisSessionFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -32,8 +31,8 @@ public class FixturesInstallerFromConfiguration extends FixturesInstallerAbstrac
 
     private static final Logger LOG = LoggerFactory.getLogger(FixturesInstallerFromConfiguration.class);
 
-    public FixturesInstallerFromConfiguration(final IsisSessionFactory isisSessionFactory) {
-        super(isisSessionFactory);
+    public FixturesInstallerFromConfiguration() {
+        super();
     }
 
     protected void addFixturesTo(final FixturesInstallerDelegate delegate) {
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/FixturesInstalledFlag.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/FixturesInstalledState.java
similarity index 58%
copy from core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/FixturesInstalledFlag.java
copy to core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/FixturesInstalledState.java
index 8eacc26..b886353 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/FixturesInstalledFlag.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/FixturesInstalledState.java
@@ -19,17 +19,41 @@
 
 package org.apache.isis.core.runtime.persistence;
 
-import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
-
 /**
- * For {@link org.apache.isis.core.runtime.system.persistence.PersistenceSessionFactory} implementations that can cache the
- * {@link PersistenceSession#isFixturesInstalled()} so is only called once per
- * application scope.
+ * 
+ * @since 2.0.0-M3
+ *
  */
-public interface FixturesInstalledFlag {
+public enum FixturesInstalledState {
+	
+	/**
+	 * application scoped state indicating fixture scripts have not been run yet
+	 */
+	not_Installed,
+	
+	/**
+	 * application scoped state indicating fixture scripts are currently in the process 
+	 * of being installed (are running)
+	 */
+	Installing,
+	
+	/**
+	 * application scoped state indicating fixture scripts have been installed (have run)
+	 */
+	Installed
 
-    public Boolean isFixturesInstalled();
-
-    public void setFixturesInstalled(Boolean fixturesInstalled);
+	;
 
+	public boolean isNotInstalled() {
+		return this == not_Installed;
+	}
+	
+	public boolean isInstalling() {
+		return this == Installing;
+	}
+	
+	public boolean isInstalled() {
+		return this == Installed;
+	}
 }
+
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/FixturesInstalledFlag.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/FixturesInstalledStateHolder.java
similarity index 74%
rename from core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/FixturesInstalledFlag.java
rename to core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/FixturesInstalledStateHolder.java
index 8eacc26..a0478ed 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/FixturesInstalledFlag.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/persistence/FixturesInstalledStateHolder.java
@@ -22,14 +22,15 @@ package org.apache.isis.core.runtime.persistence;
 import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
 
 /**
- * For {@link org.apache.isis.core.runtime.system.persistence.PersistenceSessionFactory} implementations that can cache the
- * {@link PersistenceSession#isFixturesInstalled()} so is only called once per
+ * For {@link org.apache.isis.core.runtime.system.persistence.PersistenceSessionFactory} 
+ * implementations that can cache the
+ * {@link PersistenceSession#getFixturesInstalledState()} so is only called once per
  * application scope.
  */
-public interface FixturesInstalledFlag {
+public interface FixturesInstalledStateHolder {
 
-    public Boolean isFixturesInstalled();
-
-    public void setFixturesInstalled(Boolean fixturesInstalled);
+    public FixturesInstalledState getFixturesInstalledState();
+    
+    public void setFixturesInstalledState(FixturesInstalledState fixturesInstalledState);
 
 }
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/session/ManagedObjectContext.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/session/ManagedObjectContext.java
index f512ff9..739b23b 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/session/ManagedObjectContext.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/session/ManagedObjectContext.java
@@ -12,6 +12,7 @@ import org.apache.isis.core.metamodel.spec.ManagedObjectState;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
+import org.apache.isis.core.runtime.persistence.FixturesInstalledState;
 import org.apache.isis.core.security.authentication.AuthenticationSession;
 
 /**
@@ -28,7 +29,7 @@ public interface ManagedObjectContext {
     ServiceRegistry getServiceRegistry();
     
 	Stream<ObjectAdapter> streamServiceAdapters();
-	_Tuples.Tuple2<ObjectAdapter, ObjectAction> findHomePageAction();
+	_Tuples.Tuple2<ObjectAdapter, ObjectAction> findHomePageAction(); //TODO [2033] there's also a HomepageService
 	
 	ObjectAdapter lookupService(String serviceId);
 	ObjectAdapter adapterForPojo(Object pojo);
@@ -37,7 +38,9 @@ public interface ManagedObjectContext {
 	Object fetchPersistentPojoInTransaction(RootOid rootOid);
 	
 	ManagedObjectState stateOf(Object domainObject);
+	FixturesInstalledState getFixturesInstalledState();
 	
 	void logoutAuthenticationSession();
 	
+	
 }
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/session/ManagedObjectContextBase.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/session/ManagedObjectContextBase.java
index f32a8af..54b0001 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/session/ManagedObjectContextBase.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/session/ManagedObjectContextBase.java
@@ -13,6 +13,7 @@ import org.apache.isis.core.metamodel.spec.ManagedObjectState;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
+import org.apache.isis.core.runtime.persistence.FixturesInstalledState;
 import org.apache.isis.core.runtime.system.context.IsisContext;
 import org.apache.isis.core.security.authentication.AuthenticationSession;
 
@@ -63,6 +64,13 @@ public abstract class ManagedObjectContextBase implements ManagedObjectContext {
 		return ps().lookupService(serviceId);
 	}
     
+    // -- FIXTURE SCRIPT STATE SUPPORT
+    
+    @Override //FIXME [2033] decouple from JDO
+    public FixturesInstalledState getFixturesInstalledState() {
+    	return ps().getFixturesInstalledState();
+    }
+    
     // -- HOMEPAGE LOOKUP SUPPORT
     
     @Override
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/session/ManagedObjectPersistence.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/session/ManagedObjectPersistence.java
index 485e3d4..52412ab 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/session/ManagedObjectPersistence.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/context/session/ManagedObjectPersistence.java
@@ -6,9 +6,13 @@ import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.oid.RootOid;
 import org.apache.isis.core.metamodel.spec.ManagedObjectState;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.runtime.persistence.FixturesInstalledState;
 import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
 
 /**
+ * TODO [2033] only temporary for refactoring, ultimately to be removed or refined
+ * <p>
+ * Adds a layer of abstraction on top of the yet too complex PersistenceSession.
  * 
  * @since 2.0.0-M3
  *
@@ -20,6 +24,7 @@ public interface ManagedObjectPersistence {
 	Stream<ObjectAdapter> streamServices(); //TODO [2033] use ServiceRegistry instead
 	ManagedObjectState stateOf(Object domainObject);
 	ObjectAdapter lookupService(final String serviceId); //TODO [2033] use ServiceRegistry instead
+	FixturesInstalledState getFixturesInstalledState();
 	
 	//
 	
@@ -73,7 +78,13 @@ public interface ManagedObjectPersistence {
 			public ObjectAdapter lookupService(String serviceId) {
 				return persistenceSession.lookupService(serviceId);
 			}
+
+			@Override
+			public FixturesInstalledState getFixturesInstalledState() {
+				return persistenceSession.getFixturesInstalledState();
+			}
 		};
 	}
 	
+	
 }
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 129251e..ec5422b 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
@@ -27,6 +27,8 @@ import org.apache.isis.core.metamodel.adapter.ObjectAdapterByIdProvider;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapterProvider;
 import org.apache.isis.core.metamodel.adapter.oid.RootOid;
 import org.apache.isis.core.metamodel.spec.ManagedObjectState;
+import org.apache.isis.core.runtime.persistence.FixturesInstalledState;
+import org.apache.isis.core.runtime.persistence.FixturesInstalledStateHolder;
 import org.apache.isis.core.runtime.persistence.objectstore.transaction.PersistenceCommand;
 import org.apache.isis.core.runtime.persistence.objectstore.transaction.TransactionalResource;
 import org.apache.isis.core.runtime.system.persistence.adaptermanager.ObjectAdapterContext.MementoRecreateObjectSupport;
@@ -81,36 +83,6 @@ extends
      */
     ManagedObjectState stateOf(Object pojo);
     
-//    /**
-//     * For Persistable, state can either be ATTACHED or DETACHED or DESTROYED.
-//     * @since 2.0.0-M3
-//     */
-//    boolean isAttached(Object pojo);
-//    
-//    /**
-//     * For Persistable, state can either be ATTACHED or DETACHED or DESTROYED.
-//     * @since 2.0.0-M3
-//     */
-//    boolean isDetached(Object pojo);
-//       
-//    /**
-//     * For Persistable, state can either be ATTACHED or DETACHED or DESTROYED.
-//     * @since 2.0.0-M2
-//     */
-//    boolean isDestroyed(Object pojo);
-//    
-//    
-//    /**
-//     * Tests whether this object is persistent. Instances that represent persistent objects in the 
-//     * data store return true. (DELETED || ATTACHED)
-//     * <p>
-//     * May also be 'deleted' (that is, {@link #isDestroyed(Object)} could return true).
-//     * @param pojo
-//     * @return
-//     * @since 2.0.0-M2
-//     */
-//    boolean isRepresentingPersistent(Object pojo);
-    
     /** whether pojo is recognized by the persistence layer, that is, it has an ObjectId
      * @since 2.0.0-M2*/
     boolean isRecognized(Object pojo);
@@ -184,7 +156,27 @@ extends
     static final String INSTALL_FIXTURES_KEY = "isis.persistor.datanucleus.install-fixtures";
     static final boolean INSTALL_FIXTURES_DEFAULT = false;
     
-    boolean isFixturesInstalled();
+    /**
+     * Determine if the object store has been initialized with its set of start
+     * up objects.
+     *
+     * <p>
+     * This method is called only once after the init has been called. If this flag
+     * returns <code>not_Installed</code> the framework will run the fixtures to
+     * initialise the persistor.
+     *
+     * <p>
+     * Returns the cached value of {@link #getFixturesInstalledState()
+     * whether fixtures are installed} from the
+     * {@link PersistenceSessionFactory}.
+     * <p>
+     * This caching is important because if we've determined, for a given run,
+     * that fixtures are not installed, then we don't want to change our mind by
+     * asking the object store again in another session.
+     *
+     * @see FixturesInstalledStateHolder
+     */
+    FixturesInstalledState getFixturesInstalledState();
     
     // -- MEMENTO SUPPORT
     
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionBase.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionBase.java
index a287a0a..4807a04 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionBase.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionBase.java
@@ -38,24 +38,21 @@ import org.apache.isis.core.commons.util.ToString;
 import org.apache.isis.core.metamodel.MetaModelContext;
 import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
 import org.apache.isis.core.plugins.ioc.RequestContextService;
-import org.apache.isis.core.runtime.persistence.FixturesInstalledFlag;
+import org.apache.isis.core.runtime.persistence.FixturesInstalledStateHolder;
 import org.apache.isis.core.runtime.services.changes.ChangedObjectsServiceInternal;
 import org.apache.isis.core.runtime.system.context.IsisContext;
 import org.apache.isis.core.runtime.system.transaction.IsisTransactionManager;
 import org.apache.isis.core.security.authentication.AuthenticationSession;
 import org.apache.isis.objectstore.jdo.datanucleus.persistence.queries.PersistenceQueryProcessor;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
-abstract class PersistenceSessionBase implements PersistenceSession {
-
-    // -- CONSTANTS
+import lombok.extern.slf4j.Slf4j;
 
-    protected static final Logger LOG = LoggerFactory.getLogger(PersistenceSession.class);
+@Slf4j
+abstract class PersistenceSessionBase implements PersistenceSession {
 
     // -- FIELDS
 
-    protected final FixturesInstalledFlag fixturesInstalledFlag;
+    protected final FixturesInstalledStateHolder fixturesInstalledStateHolder;
 
     protected final PersistenceQueryFactory persistenceQueryFactory;
     protected final IsisConfiguration configuration;
@@ -109,15 +106,15 @@ abstract class PersistenceSessionBase implements PersistenceSession {
     protected PersistenceSessionBase(
             final AuthenticationSession authenticationSession,
             final PersistenceManagerFactory jdoPersistenceManagerFactory,
-            final FixturesInstalledFlag fixturesInstalledFlag) {
+            final FixturesInstalledStateHolder fixturesInstalledFlag) {
 
-        if (LOG.isDebugEnabled()) {
-            LOG.debug("creating {}", this);
+        if (log.isDebugEnabled()) {
+        	log.debug("creating {}", this);
         }
 
         this.serviceInjector = IsisContext.getServiceInjector();;
         this.jdoPersistenceManagerFactory = jdoPersistenceManagerFactory;
-        this.fixturesInstalledFlag = fixturesInstalledFlag;
+        this.fixturesInstalledStateHolder = fixturesInstalledFlag;
 
         // injected
         this.configuration = _Config.getConfiguration();
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSession.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSession.java
index 34875bc..75499a7 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSession.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSession.java
@@ -126,5 +126,7 @@ public class IsisSession extends ManagedObjectContextBase {
         return getPersistenceSession().getTransactionManager();
     }
 
+	
+
 
 }
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionFactoryDefault.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionFactoryDefault.java
index 8db2b72..2243f93 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionFactoryDefault.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionFactoryDefault.java
@@ -137,8 +137,8 @@ public class IsisSessionFactoryDefault implements IsisSessionFactory {
             // installFixturesIfRequired
             //
             final FixturesInstallerFromConfiguration fixtureInstaller =
-                    new FixturesInstallerFromConfiguration(this);
-            fixtureInstaller.installFixtures();
+                    new FixturesInstallerFromConfiguration();
+            fixtureInstaller.installFixtures(); //TODO [2033] if too early, pass over 'this' ... new FixturesInstallerFromConfiguration(this) 
 
             //
             // translateServicesAndEnumConstants
diff --git a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainResourceHelper.java b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainResourceHelper.java
index 8773ce5..07f0eb8 100644
--- a/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainResourceHelper.java
+++ b/core/viewer-restfulobjects-server/src/main/java/org/apache/isis/viewer/restfulobjects/server/resources/DomainResourceHelper.java
@@ -38,6 +38,7 @@ import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
 import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
 import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
+import org.apache.isis.core.runtime.persistence.FixturesInstalledState;
 import org.apache.isis.core.security.authentication.AuthenticationSession;
 import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
 import org.apache.isis.viewer.restfulobjects.applib.client.RestfulResponse;
@@ -217,6 +218,11 @@ class DomainResourceHelper {
 			return rendererContext.findHomePageAction();
 		}
 
+		@Override
+		public FixturesInstalledState getFixturesInstalledState() {
+			return rendererContext.getFixturesInstalledState();
+		}
+
 		
 
     }