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

ahuber pushed a commit to branch ISIS-1976-rethink-object-adapters
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 2a7dd9dad4d573dd874b09188f60be9191834f8a
Author: Andi Huber <ahu...@apache.org>
AuthorDate: Mon Sep 10 10:57:54 2018 +0200

    ISIS-1976: refactor OA-by-Oid supply responsibility into new interface
    
    introduces ObjectAdapterByIdProvider
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-1976
---
 .../adapter/ObjectAdapterByIdProvider.java         |  86 +++++++++
 .../system/persistence/PersistenceSession4.java    |  79 +++-----
 .../persistence/PersistenceSession4_Decouple.java  | 213 ---------------------
 .../system/persistence/PersistenceSession5.java    |  67 ++-----
 .../system/persistence/PersistenceSession.java     |  36 ++--
 .../adaptermanager/ObjectAdapterContext.java       |  12 ++
 ...tAdapterContext_ObjectAdapterByIdProvider.java} | 129 +++++++++----
 .../wicket/model/models/EntityCollectionModel.java |  12 +-
 8 files changed, 254 insertions(+), 380 deletions(-)

diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapterByIdProvider.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapterByIdProvider.java
new file mode 100644
index 0000000..d8928bf
--- /dev/null
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/ObjectAdapterByIdProvider.java
@@ -0,0 +1,86 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.core.metamodel.adapter;
+
+import java.util.Map;
+import java.util.stream.Stream;
+
+import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.core.metamodel.adapter.concurrency.ConcurrencyChecking;
+import org.apache.isis.core.metamodel.adapter.oid.RootOid;
+
+/**
+ * 
+ * @since 2.0.0-M2
+ *
+ */
+public interface ObjectAdapterByIdProvider {
+    
+    // -- INTERFACE
+
+    ObjectAdapter adapterFor(RootOid rootOid, ConcurrencyChecking 
concurrencyChecking);
+    Map<RootOid, ObjectAdapter> adaptersFor(Stream<RootOid> rootOids, 
ConcurrencyChecking concurrencyChecking);
+    
+    /**
+     * As per {@link #adapterFor(RootOid, ConcurrencyChecking)}, with
+     * {@link ConcurrencyChecking#NO_CHECK no checking}.
+     *
+     * <p>
+     * This method  will <i>always</i> return an object, possibly indicating 
it is persistent; so make sure that you
+     * know that the oid does indeed represent an object you know exists.
+     * </p>
+     */
+    default ObjectAdapter adapterFor(final RootOid rootOid) {
+        return adapterFor(rootOid, ConcurrencyChecking.NO_CHECK);
+    }
+    
+    default Map<RootOid, ObjectAdapter> adaptersFor(Stream<RootOid> rootOids) {
+        return adaptersFor(rootOids, ConcurrencyChecking.NO_CHECK);
+    }
+    
+    
+    // -- FOR THOSE THAT IMPLEMENT THROUGH DELEGATION
+    
+    public static interface Delegating extends ObjectAdapterByIdProvider {
+        
+        @Programmatic
+        ObjectAdapterByIdProvider getObjectAdapterByIdProvider();
+        
+        @Programmatic
+        default ObjectAdapter adapterFor(RootOid rootOid, ConcurrencyChecking 
concurrencyChecking) {
+            return getObjectAdapterByIdProvider().adapterFor(rootOid, 
concurrencyChecking);
+        }
+        
+        
+        @Programmatic
+        default Map<RootOid, ObjectAdapter> adaptersFor(Stream<RootOid> 
rootOids, ConcurrencyChecking concurrencyChecking) {
+            return getObjectAdapterByIdProvider().adaptersFor(rootOids, 
concurrencyChecking);
+        }
+
+        
+    }
+
+
+   
+
+
+    
+    
+
+}
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 7ba1caa..390853a 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
@@ -18,12 +18,14 @@
  */
 package org.apache.isis.core.runtime.system.persistence;
 
+import static java.util.Objects.requireNonNull;
 import static org.apache.isis.commons.internal.base._Casts.uncheckedCast;
 
 import java.lang.reflect.Array;
 import java.lang.reflect.Modifier;
 import java.sql.Timestamp;
 import java.text.MessageFormat;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
@@ -38,7 +40,6 @@ import javax.jdo.PersistenceManagerFactory;
 import javax.jdo.identity.SingleFieldIdentity;
 import javax.jdo.listener.InstanceLifecycleListener;
 
-import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 
 import org.datanucleus.enhancement.Persistable;
@@ -54,12 +55,12 @@ import 
org.apache.isis.applib.services.bookmark.BookmarkService;
 import org.apache.isis.applib.services.command.Command;
 import org.apache.isis.applib.services.exceprecog.ExceptionRecognizer;
 import org.apache.isis.applib.services.iactn.Interaction;
-import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.core.commons.authentication.AuthenticationSession;
 import org.apache.isis.core.commons.ensure.Assert;
 import org.apache.isis.core.commons.exceptions.IsisException;
 import org.apache.isis.core.commons.factory.InstanceUtil;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapterByIdProvider;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapterProvider;
 import org.apache.isis.core.metamodel.adapter.concurrency.ConcurrencyChecking;
 import org.apache.isis.core.metamodel.adapter.oid.Oid;
@@ -127,7 +128,6 @@ implements 
IsisLifecycleListener.PersistenceSessionLifecycleManagement {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(PersistenceSession4.class);
     private ObjectAdapterContext objectAdapterContext;
-    private PersistenceSession4_Decouple mixin;
 
     /**
      * Initialize the object store so that calls to this object store access
@@ -170,7 +170,6 @@ implements 
IsisLifecycleListener.PersistenceSessionLifecycleManagement {
                 new PersistenceQueryFindUsingApplibQueryProcessor(this));
 
         objectAdapterContext = 
ObjectAdapterContext.openContext(servicesInjector, authenticationSession, 
specificationLoader, this);
-        mixin = new PersistenceSession4_Decouple(this, objectAdapterContext);
 
         // tell the proxy of all request-scoped services to instantiate the 
underlying
         // services, store onto the thread-local and inject into them...
@@ -477,6 +476,7 @@ implements 
IsisLifecycleListener.PersistenceSessionLifecycleManagement {
         return initializePropertiesAndDoCallback(adapter);
     }
 
+    //FIXME[ISIS-1976] remove
     private Object recreateViewModel(final ObjectSpecification spec, final 
String memento) {
         final ViewModelFacet facet = spec.getFacet(ViewModelFacet.class);
         if(facet == null) {
@@ -695,19 +695,16 @@ implements 
IsisLifecycleListener.PersistenceSessionLifecycleManagement {
                     public ObjectAdapter execute() {
                         LOG.debug("getObject; oid={}", oid);
 
-                        final Object pojo = loadPersistentPojo(oid);
+                        final Object pojo = fetchPersistentPojo(oid);
                         return 
objectAdapterContext.addRecreatedPojoToCache(oid, pojo);
                     }
                 });
     }
 
+    // -- FETCHING
 
-
-
-    // -- loadPersistentPojo
-
-    //TODO[ISIS-1976] used by mixin
-    Object loadPersistentPojo(final RootOid rootOid) {
+    @Override
+    public Object fetchPersistentPojo(final RootOid rootOid) {
 
         Object result;
         try {
@@ -739,14 +736,14 @@ implements 
IsisLifecycleListener.PersistenceSessionLifecycleManagement {
         return result;
     }
 
-    //TODO[ISIS-1976] used by mixin
-    Map<RootOid,Object> loadPersistentPojos(final List<RootOid> rootOids) {
+    @Override
+    public Map<RootOid,Object> fetchPersistentPojos(final List<RootOid> 
rootOids) {
 
         if(rootOids.isEmpty()) {
-            return zip(rootOids, Collections.emptyList());
+            return Collections.emptyMap();
         }
 
-        final List<Object> dnOids = _Lists.newArrayList();
+        final List<Object> dnOids = new ArrayList<>(rootOids.size());
         for (final RootOid rootOid : rootOids) {
             final Object id = JdoObjectIdSerializer.toJdoObjectId(rootOid);
             if(id instanceof SingleFieldIdentity) {
@@ -762,7 +759,7 @@ implements 
IsisLifecycleListener.PersistenceSessionLifecycleManagement {
         }
         FetchPlan fetchPlan = persistenceManager.getFetchPlan();
         fetchPlan.addGroup(FetchGroup.DEFAULT);
-        final List<Object> persistentPojos = Lists.newArrayList();
+        final List<Object> persistentPojos = new ArrayList<>(rootOids.size());
         try {
             final Collection<Object> pojos = 
uncheckedCast(persistenceManager.getObjectsById(dnOids, true));
             for (final Object pojo : pojos) {
@@ -1077,40 +1074,6 @@ implements 
IsisLifecycleListener.PersistenceSessionLifecycleManagement {
         }
     }
 
-    @Override
-    public Map<RootOid, ObjectAdapter> adaptersFor(
-            final List<RootOid> rootOids,
-            final ConcurrencyChecking concurrencyChecking) {
-
-        return mixin.adaptersFor(rootOids, concurrencyChecking);
-        }
-
-    @Override
-    public ObjectAdapter adapterFor(
-            final RootOid rootOid,
-            final ConcurrencyChecking concurrencyChecking) {
-
-        return mixin.adapterFor(rootOid, concurrencyChecking);
-            }
-
-    //TODO[ISIS-1976] used by mixin
-    Object recreatePojoTransientOrViewModel(final RootOid rootOid) {
-        final ObjectSpecification spec =
-                specificationLoader.lookupBySpecId(rootOid.getObjectSpecId());
-        final Object pojo;
-
-        if(rootOid.isViewModel()) {
-
-            final String memento = rootOid.getIdentifier();
-            pojo = recreateViewModel(spec, memento);
-
-        } else {
-            pojo = instantiateAndInjectServices(spec);
-
-        }
-        return pojo;
-    }
-
     // -- TransactionManager delegate methods
     protected IsisTransaction getCurrentTransaction() {
         return transactionManager.getCurrentTransaction();
@@ -1202,7 +1165,15 @@ implements 
IsisLifecycleListener.PersistenceSessionLifecycleManagement {
 
     @Override
     public String identifierFor(final Object pojo) {
-        return 
JdoObjectIdSerializer.toOidIdentifier(getPersistenceManager().getObjectId(pojo));
+        final Object jdoOid = getPersistenceManager().getObjectId(pojo);
+        if(jdoOid==null) {
+            return UUID.randomUUID().toString(); //FIXME[ISIS-1976] should be 
guarded against somewhere else
+        }
+        
+        requireNonNull(jdoOid, 
+                ()->String.format("Pojo of type '%s' is not recognized by 
JDO.", 
+                        pojo.getClass().getName()));
+        return JdoObjectIdSerializer.toOidIdentifier(jdoOid);
     }
 
 
@@ -1408,6 +1379,12 @@ implements 
IsisLifecycleListener.PersistenceSessionLifecycleManagement {
         return objectAdapterContext.getObjectAdapterProvider();
     }
     
+    @Override
+    public ObjectAdapterByIdProvider getObjectAdapterByIdProvider() {
+        return objectAdapterContext.getObjectAdapterByIdProvider();
+    }
+
+
 }
 
 
diff --git 
a/core/plugins/jdo-datanucleus-4/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession4_Decouple.java
 
b/core/plugins/jdo-datanucleus-4/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession4_Decouple.java
deleted file mode 100644
index de33ef0..0000000
--- 
a/core/plugins/jdo-datanucleus-4/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession4_Decouple.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.isis.core.runtime.system.persistence;
-
-import java.util.List;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.isis.commons.internal.collections._Lists;
-import org.apache.isis.commons.internal.collections._Maps;
-import org.apache.isis.core.commons.authentication.AuthenticationSession;
-import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.core.metamodel.adapter.concurrency.ConcurrencyChecking;
-import org.apache.isis.core.metamodel.adapter.oid.Oid;
-import org.apache.isis.core.metamodel.adapter.oid.RootOid;
-import org.apache.isis.core.metamodel.adapter.version.ConcurrencyException;
-import org.apache.isis.core.metamodel.adapter.version.Version;
-import org.apache.isis.core.runtime.persistence.ObjectNotFoundException;
-import org.apache.isis.core.runtime.persistence.PojoRecreationException;
-import 
org.apache.isis.core.runtime.system.persistence.adaptermanager.ObjectAdapterContext;
-
-class PersistenceSession4_Decouple  {
-
-    private static final Logger LOG = 
LoggerFactory.getLogger(PersistenceSession4_Decouple.class);
-    private final PersistenceSession4 holder;
-    private final ObjectAdapterContext objectAdapterContext;
-    private final AuthenticationSession authenticationSession;
-    private final boolean concurrencyCheckingGloballyEnabled;
-
-    protected PersistenceSession4_Decouple(PersistenceSession4 holder, 
ObjectAdapterContext objectAdapterContext) {
-        this.holder = holder;
-        this.objectAdapterContext = objectAdapterContext;
-        this.authenticationSession = holder.getAuthenticationSession();
-        this.concurrencyCheckingGloballyEnabled = 
!ConcurrencyChecking.isGloballyDisabled(holder.getConfiguration());
-    }
-
-    /**
-     * Either returns an existing {@link ObjectAdapter adapter} (as per
-     * {@link #lookupAdapterFor(Oid)}), otherwise re-creates an adapter with 
the
-     * specified (persistent) {@link Oid}.
-     *
-     * <p>
-     * Typically called when the {@link Oid} is already known, that is, when
-     * resolving an already-persisted object. Is also available for
-     * <tt>Memento</tt> support however, so {@link Oid} could also represent a
-     * {@link Oid#isTransient() transient} object.
-     *
-     * <p>
-     * The pojo itself is recreated by delegating to a {@link AdapterManager}.
-     *
-     * <p>
-     * The {@link ConcurrencyChecking} parameter determines whether 
concurrency checking is performed.
-     * If it is requested, then a check is made to ensure that the {@link 
Oid#getVersion() version}
-     * of the {@link RootOid oid} of the recreated adapter is the same as that 
of the provided {@link RootOid oid}.
-     * If the version differs, then a {@link ConcurrencyException} is thrown.
-     *
-     * <p>
-     * ALSO, even if a {@link ConcurrencyException}, then the provided {@link 
RootOid oid}'s {@link Version version}
-     * will be {@link RootOid#setVersion(Version) set} to the current
-     * value.  This allows the client to retry if they wish.
-     *
-     * @throws {@link 
org.apache.isis.core.runtime.persistence.ObjectNotFoundException} if the object 
does not exist.
-     */
-    public ObjectAdapter adapterFor(
-            final RootOid rootOid,
-            final ConcurrencyChecking concurrencyChecking) {
-
-        // attempt to locate adapter for the Oid
-        ObjectAdapter adapter = objectAdapterContext.lookupAdapterFor(rootOid);
-        if (adapter == null) {
-            // else recreate
-            try {
-                final Object pojo;
-                if(rootOid.isTransient() || rootOid.isViewModel()) {
-                    pojo = holder.recreatePojoTransientOrViewModel(rootOid);
-                } else {
-                    pojo = holder.loadPersistentPojo(rootOid);
-                }
-                adapter = 
objectAdapterContext.addRecreatedPojoToCache(rootOid, pojo);
-            } catch(ObjectNotFoundException ex) {
-                throw ex; // just rethrow
-            } catch(RuntimeException ex) {
-                throw new PojoRecreationException(rootOid, ex);
-            }
-        }
-
-        // sync versions of original, with concurrency checking if required
-        syncVersion(concurrencyChecking, adapter, rootOid);
-
-        return adapter;
-
-    }
-    
-    protected Map<RootOid,ObjectAdapter> adaptersFor(
-            final List<RootOid> rootOids,
-            final ConcurrencyChecking concurrencyChecking) {
-
-        final Map<RootOid, ObjectAdapter> adapterByOid = 
_Maps.newLinkedHashMap();
-
-        List<RootOid> notYetLoadedOids = _Lists.newArrayList();
-        for (RootOid rootOid : rootOids) {
-            // attempt to locate adapter for the Oid
-            ObjectAdapter adapter = 
objectAdapterContext.lookupAdapterFor(rootOid);
-            // handle view models or transient
-            if (adapter == null) {
-                if (rootOid.isTransient() || rootOid.isViewModel()) {
-                    final Object pojo = 
holder.recreatePojoTransientOrViewModel(rootOid);
-                    adapter = 
objectAdapterContext.addRecreatedPojoToCache(rootOid, pojo);
-                    syncVersion(concurrencyChecking, adapter, rootOid);
-                }
-            }
-            if (adapter != null) {
-                adapterByOid.put(rootOid, adapter);
-            } else {
-                // persistent oid, to load in bulk
-                notYetLoadedOids.add(rootOid);
-            }
-        }
-
-        // recreate, in bulk, all those not yet loaded
-        final Map<RootOid, Object> pojoByOid = 
holder.loadPersistentPojos(notYetLoadedOids);
-        for (Map.Entry<RootOid, Object> entry : pojoByOid.entrySet()) {
-            final RootOid rootOid = entry.getKey();
-            final Object pojo = entry.getValue();
-            if(pojo != null) {
-                ObjectAdapter adapter;
-                try {
-                    adapter = 
objectAdapterContext.addRecreatedPojoToCache(rootOid, pojo);
-                    adapterByOid.put(rootOid, adapter);
-                } catch(ObjectNotFoundException ex) {
-                    throw ex; // just rethrow
-                } catch(RuntimeException ex) {
-                    throw new PojoRecreationException(rootOid, ex);
-                }
-                syncVersion(concurrencyChecking, adapter, rootOid);
-            } else {
-                // null indicates it couldn't be loaded
-                // do nothing here...
-            }
-        }
-
-        return adapterByOid;
-    }
-
-    private void syncVersion(
-            final ConcurrencyChecking concurrencyChecking,
-            final ObjectAdapter adapter, final RootOid rootOid) {
-        // sync versions of original, with concurrency checking if required
-        Oid adapterOid = adapter.getOid();
-        if(adapterOid instanceof RootOid) {
-            final RootOid recreatedOid = (RootOid) adapterOid;
-            final RootOid originalOid = rootOid;
-
-            try {
-                if(concurrencyChecking.isChecking()) {
-
-                    // check for exception, but don't throw if suppressed 
through thread-local
-                    final Version otherVersion = originalOid.getVersion();
-                    final Version thisVersion = recreatedOid.getVersion();
-                    if( thisVersion != null &&
-                            otherVersion != null &&
-                            thisVersion.different(otherVersion)) {
-
-                        if(concurrencyCheckingGloballyEnabled && 
ConcurrencyChecking.isCurrentlyEnabled()) {
-                            LOG.info("concurrency conflict detected on {} 
({})", recreatedOid, otherVersion);
-                            final String currentUser = 
authenticationSession.getUserName();
-                            throw new ConcurrencyException(currentUser, 
recreatedOid, thisVersion, otherVersion);
-                        } else {
-                            LOG.info("concurrency conflict detected but 
suppressed, on {} ({})", recreatedOid, otherVersion);
-                        }
-                    }
-                }
-            } finally {
-                final Version originalVersion = originalOid.getVersion();
-                final Version recreatedVersion = recreatedOid.getVersion();
-                if(recreatedVersion != null && (
-                        originalVersion == null ||
-                        recreatedVersion.different(originalVersion))
-                        ) {
-                    if(LOG.isDebugEnabled()) {
-                        LOG.debug("updating version in oid, on {} ({}) to 
({})", originalOid, originalVersion, recreatedVersion);
-                    }
-                    originalOid.setVersion(recreatedVersion);
-                }
-            }
-        }
-    }
-
-
-
-
-}
-
-
-
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 2a9ec77..0fae449 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
@@ -25,6 +25,7 @@ import java.lang.reflect.Array;
 import java.lang.reflect.Modifier;
 import java.sql.Timestamp;
 import java.text.MessageFormat;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
@@ -34,18 +35,14 @@ import java.util.UUID;
 
 import javax.jdo.FetchGroup;
 import javax.jdo.FetchPlan;
-import javax.jdo.JDOHelper;
 import javax.jdo.PersistenceManager;
 import javax.jdo.PersistenceManagerFactory;
 import javax.jdo.identity.SingleFieldIdentity;
 import javax.jdo.listener.InstanceLifecycleListener;
 
-import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 
 import org.datanucleus.enhancement.Persistable;
-import org.datanucleus.enhancer.methods.IsDeleted;
-import org.datanucleus.enhancer.methods.IsPersistent;
 import org.datanucleus.exceptions.NucleusObjectNotFoundException;
 import org.datanucleus.identity.DatastoreIdImpl;
 import org.slf4j.Logger;
@@ -58,12 +55,12 @@ import 
org.apache.isis.applib.services.bookmark.BookmarkService;
 import org.apache.isis.applib.services.command.Command;
 import org.apache.isis.applib.services.exceprecog.ExceptionRecognizer;
 import org.apache.isis.applib.services.iactn.Interaction;
-import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.core.commons.authentication.AuthenticationSession;
 import org.apache.isis.core.commons.ensure.Assert;
 import org.apache.isis.core.commons.exceptions.IsisException;
 import org.apache.isis.core.commons.factory.InstanceUtil;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapterByIdProvider;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapterProvider;
 import org.apache.isis.core.metamodel.adapter.concurrency.ConcurrencyChecking;
 import org.apache.isis.core.metamodel.adapter.oid.Oid;
@@ -131,7 +128,6 @@ implements 
IsisLifecycleListener.PersistenceSessionLifecycleManagement {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(PersistenceSession5.class);
     private ObjectAdapterContext objectAdapterContext;
-    private PersistenceSession5_Decouple mixin;
 
     /**
      * Initialize the object store so that calls to this object store access
@@ -174,7 +170,6 @@ implements 
IsisLifecycleListener.PersistenceSessionLifecycleManagement {
                 new PersistenceQueryFindUsingApplibQueryProcessor(this));
 
         objectAdapterContext = 
ObjectAdapterContext.openContext(servicesInjector, authenticationSession, 
specificationLoader, this);
-        mixin = new PersistenceSession5_Decouple(this, objectAdapterContext);
 
         // tell the proxy of all request-scoped services to instantiate the 
underlying
         // services, store onto the thread-local and inject into them...
@@ -479,6 +474,7 @@ implements 
IsisLifecycleListener.PersistenceSessionLifecycleManagement {
         return initializePropertiesAndDoCallback(adapter);
     }
 
+    //FIXME[ISIS-1976] remove
     private Object recreateViewModel(final ObjectSpecification spec, final 
String memento) {
         final ViewModelFacet facet = spec.getFacet(ViewModelFacet.class);
         if(facet == null) {
@@ -697,16 +693,16 @@ implements 
IsisLifecycleListener.PersistenceSessionLifecycleManagement {
                     public ObjectAdapter execute() {
                         LOG.debug("getObject; oid={}", oid);
 
-                        final Object pojo = loadPersistentPojo(oid);
+                        final Object pojo = fetchPersistentPojo(oid);
                         return 
objectAdapterContext.addRecreatedPojoToCache(oid, pojo);
                     }
                 });
     }
 
-    // -- loadPersistentPojo
+    // -- FETCHING
 
-    //TODO[ISIS-1976] used by mixin
-    Object loadPersistentPojo(final RootOid rootOid) {
+    @Override
+    public Object fetchPersistentPojo(final RootOid rootOid) {
 
         Object result;
         try {
@@ -738,14 +734,14 @@ implements 
IsisLifecycleListener.PersistenceSessionLifecycleManagement {
         return result;
     }
 
-    //TODO[ISIS-1976] used by mixin
-    Map<RootOid,Object> loadPersistentPojos(final List<RootOid> rootOids) {
+    @Override
+    public Map<RootOid,Object> fetchPersistentPojos(final List<RootOid> 
rootOids) {
 
         if(rootOids.isEmpty()) {
-            return zip(rootOids, Collections.emptyList());
+            return Collections.emptyMap();
         }
 
-        final List<Object> dnOids = _Lists.newArrayList();
+        final List<Object> dnOids = new ArrayList<>(rootOids.size());
         for (final RootOid rootOid : rootOids) {
             final Object id = JdoObjectIdSerializer.toJdoObjectId(rootOid);
             if(id instanceof SingleFieldIdentity) {
@@ -761,7 +757,7 @@ implements 
IsisLifecycleListener.PersistenceSessionLifecycleManagement {
         }
         FetchPlan fetchPlan = persistenceManager.getFetchPlan();
         fetchPlan.addGroup(FetchGroup.DEFAULT);
-        final List<Object> persistentPojos = Lists.newArrayList();
+        final List<Object> persistentPojos = new ArrayList<>(rootOids.size());
         try {
             final Collection<Object> pojos = 
uncheckedCast(persistenceManager.getObjectsById(dnOids, true));
             for (final Object pojo : pojos) {
@@ -1074,40 +1070,6 @@ implements 
IsisLifecycleListener.PersistenceSessionLifecycleManagement {
         }
     }
 
-    @Override
-    public Map<RootOid, ObjectAdapter> adaptersFor(
-            final List<RootOid> rootOids, 
-            final ConcurrencyChecking concurrencyChecking) {
-
-        return mixin.adaptersFor(rootOids, concurrencyChecking);
-    }
-
-    @Override
-    public ObjectAdapter adapterFor(
-            final RootOid rootOid,
-            final ConcurrencyChecking concurrencyChecking) {
-
-        return mixin.adapterFor(rootOid, concurrencyChecking);
-    }
-
-    //TODO[ISIS-1976] used by mixin
-    Object recreatePojoTransientOrViewModel(final RootOid rootOid) {
-        final ObjectSpecification spec =
-                specificationLoader.lookupBySpecId(rootOid.getObjectSpecId());
-        final Object pojo;
-
-        if(rootOid.isViewModel()) {
-
-            final String memento = rootOid.getIdentifier();
-            pojo = recreateViewModel(spec, memento);
-
-        } else {
-            pojo = instantiateAndInjectServices(spec);
-
-        }
-        return pojo;
-    }
-
     // -- TransactionManager delegate methods
     protected IsisTransaction getCurrentTransaction() {
         return transactionManager.getCurrentTransaction();
@@ -1409,6 +1371,11 @@ implements 
IsisLifecycleListener.PersistenceSessionLifecycleManagement {
     public ObjectAdapterProvider getObjectAdapterProvider() {
         return objectAdapterContext.getObjectAdapterProvider();
     }
+    
+    @Override
+    public ObjectAdapterByIdProvider getObjectAdapterByIdProvider() {
+        return objectAdapterContext.getObjectAdapterByIdProvider();
+    }
 
 
 }
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 eec2996..2354136 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,8 +27,8 @@ import 
org.apache.isis.applib.services.bookmark.BookmarkService.FieldResetPolicy
 import org.apache.isis.core.commons.components.SessionScopedComponent;
 import org.apache.isis.core.commons.config.IsisConfiguration;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapterByIdProvider;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapterProvider;
-import org.apache.isis.core.metamodel.adapter.concurrency.ConcurrencyChecking;
 import org.apache.isis.core.metamodel.adapter.oid.ParentedCollectionOid;
 import org.apache.isis.core.metamodel.adapter.oid.RootOid;
 import org.apache.isis.core.metamodel.services.ServicesInjector;
@@ -39,7 +39,12 @@ import 
org.apache.isis.core.runtime.runner.opts.OptionHandlerFixtureAbstract;
 import 
org.apache.isis.core.runtime.system.persistence.adaptermanager.ObjectAdapterContext.MementoRecreateObjectSupport;
 import org.apache.isis.core.runtime.system.transaction.IsisTransactionManager;
 
-public interface PersistenceSession extends ObjectAdapterProvider.Delegating, 
TransactionalResource, SessionScopedComponent {
+public interface PersistenceSession 
+extends 
+    ObjectAdapterProvider.Delegating,
+    ObjectAdapterByIdProvider.Delegating,
+    TransactionalResource, 
+    SessionScopedComponent {
 
     // -- CONSTANTS
 
@@ -55,27 +60,8 @@ public interface PersistenceSession extends 
ObjectAdapterProvider.Delegating, Tr
 
     MementoRecreateObjectSupport mementoSupport();
 
-    ObjectAdapter adapterFor(RootOid rootOid, ConcurrencyChecking 
concurrencyChecking);
-    Map<RootOid, ObjectAdapter> adaptersFor(List<RootOid> rootOids, 
ConcurrencyChecking concurrencyChecking);
     ObjectAdapter adapterForAny(RootOid rootOid);
     <T> List<ObjectAdapter> allMatchingQuery(final Query<T> query);
-    
-    /**
-     * As per {@link #adapterFor(RootOid, ConcurrencyChecking)}, with
-     * {@link ConcurrencyChecking#NO_CHECK no checking}.
-     *
-     * <p>
-     * This method  will <i>always</i> return an object, possibly indicating 
it is persistent; so make sure that you
-     * know that the oid does indeed represent an object you know exists.
-     * </p>
-     */
-    default ObjectAdapter adapterFor(final RootOid rootOid) {
-        return adapterFor(rootOid, ConcurrencyChecking.NO_CHECK);
-    }
-    
-    default Map<RootOid, ObjectAdapter> adaptersFor(List<RootOid> rootOids) {
-        return adaptersFor(rootOids, ConcurrencyChecking.NO_CHECK);
-    }
 
     // --
 
@@ -111,6 +97,10 @@ public interface PersistenceSession extends 
ObjectAdapterProvider.Delegating, Tr
     boolean isRepresentingPersistent(Object pojo);
     /**@since 2.0.0-M2*/
     boolean isDestroyed(Object pojo);
+    /**@since 2.0.0-M2*/
+    Object fetchPersistentPojo(RootOid rootOid);
+    /**@since 2.0.0-M2*/
+    Map<RootOid, Object> fetchPersistentPojos(List<RootOid> rootOids);
 
     /**
      * Convenient equivalent to {@code getPersistenceManager()}.
@@ -167,8 +157,6 @@ public interface PersistenceSession extends 
ObjectAdapterProvider.Delegating, Tr
 
     void resolve(Object parent);
 
-
-
-
+    
 
 }
diff --git 
a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext.java
 
b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext.java
index 6f5df49..f4a21fa 100644
--- 
a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext.java
+++ 
b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext.java
@@ -29,7 +29,9 @@ import 
org.apache.isis.core.commons.authentication.AuthenticationSession;
 import org.apache.isis.core.commons.ensure.Assert;
 import org.apache.isis.core.commons.ensure.IsisAssertException;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapterByIdProvider;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapterProvider;
+import org.apache.isis.core.metamodel.adapter.concurrency.ConcurrencyChecking;
 import org.apache.isis.core.metamodel.adapter.oid.Oid;
 import org.apache.isis.core.metamodel.adapter.oid.ParentedCollectionOid;
 import org.apache.isis.core.metamodel.adapter.oid.RootOid;
@@ -131,6 +133,7 @@ public class ObjectAdapterContext {
     private final ObjectAdapterContext_MementoSupport mementoSupportMixin;
     private final ObjectAdapterContext_ServiceLookup serviceLookupMixin;
     private final ObjectAdapterContext_NewIdentifier newIdentifierMixin;
+    private final ObjectAdapterContext_ObjectAdapterByIdProvider byIdMixin;
     
     private ObjectAdapterContext(
             ServicesInjector servicesInjector, 
@@ -144,6 +147,7 @@ public class ObjectAdapterContext {
         this.mementoSupportMixin = new 
ObjectAdapterContext_MementoSupport(this, persistenceSession);
         this.serviceLookupMixin = new ObjectAdapterContext_ServiceLookup(this, 
servicesInjector);
         this.newIdentifierMixin = new ObjectAdapterContext_NewIdentifier(this, 
persistenceSession);
+        this.byIdMixin = new 
ObjectAdapterContext_ObjectAdapterByIdProvider(this, persistenceSession, 
authenticationSession);
         
         this.persistenceSession = persistenceSession;
         this.servicesInjector = servicesInjector;
@@ -233,6 +237,12 @@ public class ObjectAdapterContext {
         return serviceLookupMixin.lookupServiceAdapterFor(rootOid);
     }
     
+    // -- BY-ID SUPPORT
+    
+    public ObjectAdapterByIdProvider getObjectAdapterByIdProvider() {
+        return byIdMixin;
+    }
+    
     // -- FACTORIES
     
     // package private
@@ -465,6 +475,8 @@ public class ObjectAdapterContext {
         return newAdapter;
     }
 
+
+
    
 
 
diff --git 
a/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession5_Decouple.java
 
b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterByIdProvider.java
similarity index 71%
rename from 
core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession5_Decouple.java
rename to 
core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterByIdProvider.java
index e40f9c3..c4a8af3 100644
--- 
a/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSession5_Decouple.java
+++ 
b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/ObjectAdapterContext_ObjectAdapterByIdProvider.java
@@ -16,43 +16,64 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.core.runtime.system.persistence;
+package org.apache.isis.core.runtime.system.persistence.adaptermanager;
 
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Stream;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.commons.internal.collections._Maps;
-import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.commons.authentication.AuthenticationSession;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapterByIdProvider;
 import org.apache.isis.core.metamodel.adapter.concurrency.ConcurrencyChecking;
 import org.apache.isis.core.metamodel.adapter.oid.Oid;
 import org.apache.isis.core.metamodel.adapter.oid.RootOid;
 import org.apache.isis.core.metamodel.adapter.version.ConcurrencyException;
 import org.apache.isis.core.metamodel.adapter.version.Version;
+import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
+import org.apache.isis.core.metamodel.services.ServicesInjector;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
 import org.apache.isis.core.runtime.persistence.ObjectNotFoundException;
 import org.apache.isis.core.runtime.persistence.PojoRecreationException;
-import 
org.apache.isis.core.runtime.system.persistence.adaptermanager.ObjectAdapterContext;
+import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
 
-class PersistenceSession5_Decouple  {
-
-    private static final Logger LOG = 
LoggerFactory.getLogger(PersistenceSession5_Decouple.class);
-    private final PersistenceSession5 holder;
+/**
+ * package private mixin for ObjectAdapterContext
+ * <p>
+ * Responsibility: creates RootOids 
+ * </p> 
+ * @since 2.0.0-M2
+ */
+class ObjectAdapterContext_ObjectAdapterByIdProvider implements 
ObjectAdapterByIdProvider {
+    
+    
+    private static final Logger LOG = 
LoggerFactory.getLogger(ObjectAdapterContext_ObjectAdapterByIdProvider.class);
     private final ObjectAdapterContext objectAdapterContext;
+    private final PersistenceSession persistenceSession;
+    private final ServicesInjector servicesInjector;
+    private final SpecificationLoader specificationLoader;
     private final AuthenticationSession authenticationSession;
     private final boolean concurrencyCheckingGloballyEnabled;
-
-    protected PersistenceSession5_Decouple(PersistenceSession5 holder, 
ObjectAdapterContext objectAdapterContext) {
-        this.holder = holder;
+    
+    
+    ObjectAdapterContext_ObjectAdapterByIdProvider(ObjectAdapterContext 
objectAdapterContext,
+            PersistenceSession persistenceSession, AuthenticationSession 
authenticationSession) {
         this.objectAdapterContext = objectAdapterContext;
-        this.authenticationSession = holder.getAuthenticationSession();
-        this.concurrencyCheckingGloballyEnabled = 
!ConcurrencyChecking.isGloballyDisabled(holder.getConfiguration());
+        this.persistenceSession = persistenceSession;
+        this.servicesInjector = persistenceSession.getServicesInjector();
+        this.specificationLoader = servicesInjector.getSpecificationLoader();
+        this.authenticationSession = authenticationSession;
+        
+        this.concurrencyCheckingGloballyEnabled = 
+                
!ConcurrencyChecking.isGloballyDisabled(persistenceSession.getConfiguration());
     }
-
+    
     /**
      * Either returns an existing {@link ObjectAdapter adapter} (as per
      * {@link #lookupAdapterFor(Oid)}), otherwise re-creates an adapter with 
the
@@ -65,7 +86,7 @@ class PersistenceSession5_Decouple  {
      * {@link Oid#isTransient() transient} object.
      *
      * <p>
-     * The pojo itself is recreated by delegating to a {@link AdapterManager}.
+     * The pojo itself is recreated by delegating to a FIXME:AdapterManager
      *
      * <p>
      * The {@link ConcurrencyChecking} parameter determines whether 
concurrency checking is performed.
@@ -80,11 +101,12 @@ class PersistenceSession5_Decouple  {
      *
      * @throws {@link 
org.apache.isis.core.runtime.persistence.ObjectNotFoundException} if the object 
does not exist.
      */
+    @Override
     public ObjectAdapter adapterFor(
             final RootOid rootOid,
             final ConcurrencyChecking concurrencyChecking) {
-        
-        /* FIXME[ISIS-1976] guard against service lookup
+                
+        /* FIXME[ISIS-1976] 
          * https://github.com/apache/isis/pull/121#discussion_r215889748
          * 
          * Eventually I'm hoping that this code will simplify and then become 
pluggable.
@@ -101,10 +123,11 @@ class PersistenceSession5_Decouple  {
          * into some other datastore. So really my "PersistenceProvider" is a
          * generalization of that concept).
          */
-
+        
+        //FIXME[ISIS-1976] remove guard
         final ObjectAdapter serviceAdapter = 
objectAdapterContext.lookupServiceAdapterFor(rootOid);
         if (serviceAdapter != null) {
-            _Exceptions.unexpectedCodeReach();
+            //_Exceptions.unexpectedCodeReach();
             return serviceAdapter;
         }
         
@@ -115,9 +138,9 @@ class PersistenceSession5_Decouple  {
             try {
                 final Object pojo;
                 if(rootOid.isTransient() || rootOid.isViewModel()) {
-                    pojo = holder.recreatePojoTransientOrViewModel(rootOid);
+                    pojo = recreatePojoTransientOrViewModel(rootOid);
                 } else {
-                    pojo = holder.loadPersistentPojo(rootOid);
+                    pojo = persistenceSession.fetchPersistentPojo(rootOid);
                 }
                 adapter = 
objectAdapterContext.addRecreatedPojoToCache(rootOid, pojo);
             } catch(ObjectNotFoundException ex) {
@@ -131,23 +154,25 @@ class PersistenceSession5_Decouple  {
         syncVersion(concurrencyChecking, adapter, rootOid);
 
         return adapter;
-
+        
     }
     
-    protected Map<RootOid,ObjectAdapter> adaptersFor(
-            final List<RootOid> rootOids,
+    @Override
+    public Map<RootOid,ObjectAdapter> adaptersFor(
+            final Stream<RootOid> rootOids,
             final ConcurrencyChecking concurrencyChecking) {
 
         final Map<RootOid, ObjectAdapter> adapterByOid = 
_Maps.newLinkedHashMap();
 
         List<RootOid> notYetLoadedOids = _Lists.newArrayList();
-        for (RootOid rootOid : rootOids) {
-            // attempt to locate adapter for the Oid
+        
+        rootOids.forEach(rootOid->{
+         // attempt to locate adapter for the Oid
             ObjectAdapter adapter = 
objectAdapterContext.lookupAdapterFor(rootOid);
             // handle view models or transient
             if (adapter == null) {
                 if (rootOid.isTransient() || rootOid.isViewModel()) {
-                    final Object pojo = 
holder.recreatePojoTransientOrViewModel(rootOid);
+                    final Object pojo = 
recreatePojoTransientOrViewModel(rootOid);
                     adapter = 
objectAdapterContext.addRecreatedPojoToCache(rootOid, pojo);
                     syncVersion(concurrencyChecking, adapter, rootOid);
                 }
@@ -158,10 +183,10 @@ class PersistenceSession5_Decouple  {
                 // persistent oid, to load in bulk
                 notYetLoadedOids.add(rootOid);
             }
-        }
-
+        });
+        
         // recreate, in bulk, all those not yet loaded
-        final Map<RootOid, Object> pojoByOid = 
holder.loadPersistentPojos(notYetLoadedOids);
+        final Map<RootOid, Object> pojoByOid = 
persistenceSession.fetchPersistentPojos(notYetLoadedOids);
         for (Map.Entry<RootOid, Object> entry : pojoByOid.entrySet()) {
             final RootOid rootOid = entry.getKey();
             final Object pojo = entry.getValue();
@@ -184,7 +209,42 @@ class PersistenceSession5_Decouple  {
 
         return adapterByOid;
     }
+    
+    // -- HELPER
+    
+    private Object recreatePojoTransientOrViewModel(final RootOid rootOid) {
+        final ObjectSpecification spec =
+                specificationLoader.lookupBySpecId(rootOid.getObjectSpecId());
+        final Object pojo;
 
+        if(rootOid.isViewModel()) {
+
+            final String memento = rootOid.getIdentifier();
+            pojo = recreateViewModel(spec, memento);
+
+        } else {
+            pojo = persistenceSession.instantiateAndInjectServices(spec);
+
+        }
+        return pojo;
+    }
+    
+    private Object recreateViewModel(final ObjectSpecification spec, final 
String memento) {
+        final ViewModelFacet facet = spec.getFacet(ViewModelFacet.class);
+        if(facet == null) {
+            throw new IllegalArgumentException("spec does not have 
ViewModelFacet; spec is " + spec.getFullIdentifier());
+        }
+
+        final Object viewModelPojo;
+        if(facet.getRecreationMechanism().isInitializes()) {
+            viewModelPojo = 
persistenceSession.instantiateAndInjectServices(spec);
+            facet.initialize(viewModelPojo, memento);
+        } else {
+            viewModelPojo = facet.instantiate(spec.getCorrespondingClass(), 
memento);
+        }
+        return viewModelPojo;
+    }
+    
     private void syncVersion(
             final ConcurrencyChecking concurrencyChecking,
             final ObjectAdapter adapter, final RootOid rootOid) {
@@ -228,11 +288,6 @@ class PersistenceSession5_Decouple  {
             }
         }
     }
-
-
-
-
-}
-
-
-
+    
+    
+}
\ No newline at end of file
diff --git 
a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityCollectionModel.java
 
b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityCollectionModel.java
index 5970611..9f86432 100644
--- 
a/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityCollectionModel.java
+++ 
b/core/viewer-wicket-model/src/main/java/org/apache/isis/viewer/wicket/model/models/EntityCollectionModel.java
@@ -19,6 +19,8 @@
 
 package org.apache.isis.viewer.wicket.model.models;
 
+import static org.apache.isis.commons.internal.base._NullSafe.stream;
+
 import java.io.Serializable;
 import java.util.Collection;
 import java.util.Collections;
@@ -97,18 +99,18 @@ UiHintContainer {
 
                 final PersistenceSession persistenceSession = 
model.getPersistenceSession();
 
-                final List<RootOid> rootOids =
-                        _Lists.transform(model.mementoList, 
ObjectAdapterMemento.Functions.toOid());
-
+                final Stream<RootOid> rootOids = stream(model.mementoList)
+                        .map(ObjectAdapterMemento.Functions.toOid());
+                
                 final Map<RootOid, ObjectAdapter> adaptersByOid = 
persistenceSession.adaptersFor(rootOids);
                 final Collection<ObjectAdapter> adapterList = 
adaptersByOid.values();
-                return _NullSafe.stream(adapterList)
+                return stream(adapterList)
                         .filter(_NullSafe::isPresent)
                         .collect(Collectors.toList());
             }
 
             private Iterable<ObjectAdapter> loadOneByOne(final 
EntityCollectionModel model) {
-                return _NullSafe.stream(model.mementoList)
+                return stream(model.mementoList)
                         .map(ObjectAdapterMemento.Functions.fromMemento(
                                 ConcurrencyChecking.NO_CHECK,
                                 model.getPersistenceSession(),

Reply via email to