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

[isis] 01/04: ISIS-2033: remove ParentedOid

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

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

commit f8526fb09f2d86f443cc9cf8bf73a0d7ea7d4027
Author: Andi Huber <ah...@apache.org>
AuthorDate: Tue Dec 22 18:43:05 2020 +0100

    ISIS-2033: remove ParentedOid
---
 .../isis/core/metamodel/adapter/oid/Oid.java       |  14 --
 .../core/metamodel/adapter/oid/Oid_Marshaller.java |  16 +--
 .../core/metamodel/adapter/oid/Oid_Parented.java   | 133 -----------------
 .../core/metamodel/adapter/oid/ParentedOid.java    |  50 -------
 .../oid/CollectionOidTest_valueSemantics.java      |  48 -------
 .../oid/OidMarshallerTest_roundtripping.java       |  10 --
 .../adapter/oid/OidMarshallerTest_unmarshal.java   |  29 ----
 .../objectadapter/ObjectAdapterContext.java        |  19 +--
 .../jdo/integration/objectadapter/_Factories.java  |  37 +++--
 .../jdo/integration/oid/JdoObjectIdSerializer.java |   8 --
 .../persistence/IsisLifecycleListener.java         |  27 ++--
 .../persistence/PersistenceSession.java            |   6 -
 .../persistence/PersistenceSession5.java           | 157 +++++++++------------
 .../jdo/integration/persistence/_Utils.java        |  61 +++++++-
 .../integration/testing/PojoAdapterBuilder.java    |   3 +-
 15 files changed, 165 insertions(+), 453 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid.java
index 28cb756..17807df 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid.java
@@ -24,10 +24,8 @@ import java.io.Serializable;
 import org.apache.isis.applib.annotation.Value;
 import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.core.metamodel.spec.ObjectSpecId;
-import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
 import org.apache.isis.schema.common.v2.OidDto;
 
-
 /**
  * An immutable identifier for either a root object (subtype {@link RootOid}) or
  * a parented collection (subtype {@link ParentedOid}).
@@ -56,8 +54,6 @@ public interface Oid extends Serializable {
 
     public static interface Marshaller {
 
-        String marshal(ParentedOid parentedOid);
-
         String marshal(RootOid rootOid);
 
         String joinAsOid(String domainType, String instanceId);
@@ -107,16 +103,6 @@ public interface Oid extends Serializable {
             return Oid_Root.of(objectSpecId, identifier);
         }
         
-        // -- PARENTED COLLECTIONS
-
-        public static ParentedOid parented(RootOid parent, OneToManyAssociation oneToMany) {
-            return Oid_Parented.ofOneToManyId(parent, oneToMany.getId());
-        }
-
-        public static ParentedOid parentedForTesting(RootOid parent, String oneToManyId) {
-            return Oid_Parented.ofOneToManyId(parent, oneToManyId);
-        }
-        
     }
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid_Marshaller.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid_Marshaller.java
index 7ee1308..2b73e03 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid_Marshaller.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid_Marshaller.java
@@ -176,18 +176,10 @@ final class Oid_Marshaller implements Oid.Marshaller, Oid.Unmarshaller {
                 throw _Exceptions.illegalArgument("Aggregated Oids are no longer supported");
             }
         } else {
-            final String oidStrWithoutCollectionName = getGroup(matcher, 1);
-
-            final String parentOidStr = oidStrWithoutCollectionName;
-
-            RootOid parentOid = this.unmarshal(parentOidStr, RootOid.class);
-            ensureCorrectType(oidStr, requestedType, ParentedOid.class);
-            return _Casts.uncheckedCast( Oid_Parented.ofOneToManyId(parentOid, oneToManyId) );
+            throw _Exceptions.illegalArgument("Parented Oids are no longer supported.");
         }
     }
 
-
-
     private static class AggregateOidPart {
         AggregateOidPart(String objectType, String localId) {
             this.objectType = objectType;
@@ -230,10 +222,4 @@ final class Oid_Marshaller implements Oid.Marshaller, Oid.Unmarshaller {
         return rootOid.getObjectSpecId() + SEPARATOR + rootOid.getIdentifier();
     }
 
-    @Override
-    public String marshal(ParentedOid parentedOid) {
-        return parentedOid.getParentOid().enString() + SEPARATOR_PARENTED + parentedOid.getName();
-    }
-
-
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid_Parented.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid_Parented.java
deleted file mode 100644
index 00f0d45..0000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/Oid_Parented.java
+++ /dev/null
@@ -1,133 +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.metamodel.adapter.oid;
-
-import java.io.IOException;
-import java.util.Objects;
-
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
-
-import static org.apache.isis.commons.internal.base._With.requires;
-import static org.apache.isis.core.metamodel.adapter.oid.Oid.marshaller;
-import static org.apache.isis.core.metamodel.adapter.oid.Oid.unmarshaller;
-
-final class Oid_Parented implements ParentedOid {
-
-    private static final long serialVersionUID = 2L;
-
-    private final String oneToManyId;
-    private final int hashCode;
-
-    private final RootOid parentRootOid;
-
-    static Oid_Parented ofOneToManyId(RootOid parentRootOid, String oneToManyId) {
-        return new Oid_Parented(parentRootOid, oneToManyId);
-    }
-
-    private Oid_Parented(RootOid parentRootOid, String oneToManyId) {
-        requires(parentRootOid, "parentRootOid");
-        this.parentRootOid = parentRootOid;
-        this.oneToManyId = oneToManyId;
-        this.hashCode = calculateHash();
-    }
-
-    @Override
-    public RootOid getParentOid() {
-        return parentRootOid;
-    }
-    
-    @Override
-    public ObjectSpecId getObjectSpecId() {
-        return getParentOid().getObjectSpecId();
-    }
-
-    public static Oid_Parented deString(String oidStr) {
-        return unmarshaller().unmarshal(oidStr, Oid_Parented.class);
-    }
-
-    @Override
-    public String enString() {
-        return marshaller().marshal(this);
-    }
-
-    private Oid_Parented(Oid_Parented oid) throws IOException {
-        this.parentRootOid = oid.getParentOid();
-        this.oneToManyId = oid.oneToManyId;
-        this.hashCode = calculateHash();
-    }
-
-    @Override
-    public String getName() {
-        return oneToManyId;
-    }
-
-
-    // /////////////////////////////////////////////////////////
-    // toString
-    // /////////////////////////////////////////////////////////
-
-    @Override
-    public String toString() {
-        return enString();
-    }
-
-    // /////////////////////////////////////////////////////////
-    // Value semantics
-    // /////////////////////////////////////////////////////////
-
-    @Override
-    public boolean equals(final Object other) {
-        if (other == this) {
-            return true;
-        }
-        if (other == null) {
-            return false;
-        }
-        if (getClass() != other.getClass()) {
-            return false;
-        }
-        return equals((Oid_Parented) other);
-    }
-
-    public boolean equals(final Oid_Parented other) {
-        return Objects.equals(other.getParentOid(), getParentOid()) 
-                && Objects.equals(other.oneToManyId, oneToManyId);
-    }
-
-
-    @Override
-    public int hashCode() {
-        return hashCode;
-    }
-
-    private int calculateHash() {
-        return Objects.hash(getParentOid(), oneToManyId);
-    }
-
-    /**
-     * When the RootOid is persisted, all its &quot;children&quot;
-     * need updating similarly.
-     */
-    public Oid_Parented asPersistent(RootOid newParentRootOid) {
-        return new Oid_Parented(newParentRootOid, oneToManyId);
-    }
-
-
-}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/ParentedOid.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/ParentedOid.java
deleted file mode 100644
index 04773d6..0000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/adapter/oid/ParentedOid.java
+++ /dev/null
@@ -1,50 +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.metamodel.adapter.oid;
-
-import org.apache.isis.applib.annotation.Collection;
-import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
-
-import static org.apache.isis.core.metamodel.adapter.oid.Oid.unmarshaller;
-
-/**
- * Used as the {@link Oid} for {@link OneToManyAssociation} (collections).
- */
-public interface ParentedOid extends Oid {
-
-    /**
-     * object identifier of the domain object that is holding the {@link OneToManyAssociation}
-     * this instance is representing
-     */
-    RootOid getParentOid();
-
-    /**
-     * id of the {@link OneToManyAssociation} this instance is representing, that is 
-     * the member name, that is annotated with {@link Collection}
-     */
-    String getName();
-
-    // -- DECODE FROM STRING
-
-    public static ParentedOid deString(String enString) {
-        return unmarshaller().unmarshal(enString, ParentedOid.class);
-    }
-
-}
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/CollectionOidTest_valueSemantics.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/CollectionOidTest_valueSemantics.java
deleted file mode 100644
index 6d56541..0000000
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/CollectionOidTest_valueSemantics.java
+++ /dev/null
@@ -1,48 +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.metamodel.adapter.oid;
-
-import java.util.Arrays;
-import java.util.List;
-
-import org.apache.isis.core.internaltestsupport.contract.ValueTypeContractTestAbstract;
-import org.apache.isis.core.metamodel.spec.ObjectSpecId;
-
-public class CollectionOidTest_valueSemantics 
-extends ValueTypeContractTestAbstract<ParentedOid> {
-
-    private final RootOid parent = Oid.Factory.root(ObjectSpecId.of("CUS"), "123");
-    private final RootOid otherParent = Oid.Factory.root(ObjectSpecId.of("CUS"), "124");
-
-    @Override
-    protected List<ParentedOid> getObjectsWithSameValue() {
-        return Arrays.asList(
-                Oid.Factory.parentedForTesting(parent, "456"),
-                Oid.Factory.parentedForTesting(parent, "456"),
-                Oid.Factory.parentedForTesting(parent, "456"));
-    }
-
-    @Override
-    protected List<ParentedOid> getObjectsWithDifferentValue() {
-        return Arrays.asList(
-                Oid.Factory.parentedForTesting(otherParent, "456"),
-                Oid.Factory.parentedForTesting(parent, "457"));
-    }
-
-}
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/OidMarshallerTest_roundtripping.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/OidMarshallerTest_roundtripping.java
index ff3e49b..e65f99a 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/OidMarshallerTest_roundtripping.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/OidMarshallerTest_roundtripping.java
@@ -36,16 +36,6 @@ public class OidMarshallerTest_roundtripping {
         final RootOid deString = RootOid.deString(enString);
         assertThat(deString, is(oid));
     }
-
-    @Test
-    public void collectionOid() {
-        RootOid parentOid = Oid.Factory.root(ObjectSpecId.of("CUS"), "123");
-        ParentedOid oid = Oid.Factory.parentedForTesting(parentOid, "items");
-
-        final String enString = oid.enString();
-        final ParentedOid deString = ParentedOid.deString(enString);
-        assertThat(deString, is(oid));
-    }
     
     @Test
     public void rootOid_withLegacyVersionIgnored() {
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/OidMarshallerTest_unmarshal.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/OidMarshallerTest_unmarshal.java
index 1bab721..205e9ae 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/OidMarshallerTest_unmarshal.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/adapter/oid/OidMarshallerTest_unmarshal.java
@@ -109,35 +109,6 @@ public class OidMarshallerTest_unmarshal {
         assertThat(oid, equalTo((Oid)rootOid));
     }
 
-    @Test
-    public void collectionOfPersistentRoot() {
-        final String oidStr = "CUS:123$items";
-
-        final ParentedOid collectionOid = oidMarshaller.unmarshal(oidStr, ParentedOid.class);
-        assertThat(collectionOid.getParentOid(), is(oidMarshaller.unmarshal("CUS:123", RootOid.class)));
-        assertThat(collectionOid.getName(), is("items"));
-
-        final Oid oid = oidMarshaller.unmarshal(oidStr, Oid.class);
-        assertThat(oid, equalTo((Oid)collectionOid));
-    }
-
-    @Test
-    public void collectionOfTransientRoot() {
-        final String oidStr = "!CUS:123$items";
-
-        final ParentedOid collectionOid = oidMarshaller.unmarshal(oidStr, ParentedOid.class);
-        assertThat(collectionOid.getParentOid(), is(oidMarshaller.unmarshal("!CUS:123", RootOid.class)));
-        assertThat(collectionOid.getName(), is("items"));
-
-        final Oid oid = oidMarshaller.unmarshal(oidStr, Oid.class);
-        assertThat(oid, equalTo((Oid)collectionOid));
-    }
-
-
-    @Test(expected=IllegalArgumentException.class)
-    public void collection_forRoot_oidStr() {
-        oidMarshaller.unmarshal("CUS:123", ParentedOid.class);
-    }
 
     @Test(expected=IllegalArgumentException.class)
     public void badPattern() {
diff --git a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/objectadapter/ObjectAdapterContext.java b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/objectadapter/ObjectAdapterContext.java
index e600019..9eb0ad8 100644
--- a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/objectadapter/ObjectAdapterContext.java
+++ b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/objectadapter/ObjectAdapterContext.java
@@ -19,8 +19,7 @@
 package org.apache.isis.persistence.jdo.integration.objectadapter;
 
 import org.apache.isis.applib.services.inject.ServiceInjector;
-import org.apache.isis.core.metamodel.adapter.oid.Oid;
-import org.apache.isis.core.metamodel.adapter.oid.ParentedOid;
+import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.metamodel.adapter.oid.RootOid;
 import org.apache.isis.core.metamodel.context.MetaModelContext;
 import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
@@ -107,7 +106,7 @@ final public class ObjectAdapterContext {
         return adapter;
     }
 
-    public ObjectAdapter recreatePojo(Oid oid, Object recreatedPojo) {
+    public ObjectAdapter recreatePojo(RootOid oid, Object recreatedPojo) {
         final ObjectAdapter createdAdapter = createRootOrAggregatedAdapter(oid, recreatedPojo);
         return injectServices(createdAdapter);
     }
@@ -124,20 +123,14 @@ final public class ObjectAdapterContext {
         return adapter;
     }
 
-    // package private
-    ObjectAdapter createRootOrAggregatedAdapter(final Oid oid, final Object pojo) {
-        final ObjectAdapter createdAdapter;
+    private ObjectAdapter createRootOrAggregatedAdapter(final RootOid oid, final Object pojo) {
         if(oid instanceof RootOid) {
             final RootOid rootOid = (RootOid) oid;
-            createdAdapter = _Factories.createRootAdapter(pojo, rootOid, getSpecificationLoader());
-        } else /*if (oid instanceof CollectionOid)*/ {
-            final ParentedOid collectionOid = (ParentedOid) oid;
-            createdAdapter = _Factories.createCollectionAdapter(pojo, collectionOid, getSpecificationLoader());
-        }
-        return createdAdapter;
+            return _Factories.createRootAdapter(pojo, rootOid, getSpecificationLoader());
+        } 
+        throw _Exceptions.illegalArgument("Parented Oids are no longer supported.");
     }
 
-
     // -- OBJECT ADAPTER PROVIDER SUPPORT
 
     public ObjectAdapterProvider getObjectAdapterProvider() {
diff --git a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/objectadapter/_Factories.java b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/objectadapter/_Factories.java
index fd3e71f..4087147 100644
--- a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/objectadapter/_Factories.java
+++ b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/objectadapter/_Factories.java
@@ -18,10 +18,7 @@
  */
 package org.apache.isis.persistence.jdo.integration.objectadapter;
 
-import org.apache.isis.core.metamodel.adapter.oid.Oid;
-import org.apache.isis.core.metamodel.adapter.oid.ParentedOid;
 import org.apache.isis.core.metamodel.adapter.oid.RootOid;
-import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
 import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
 
 import lombok.NonNull;
@@ -36,23 +33,23 @@ final class _Factories {
         return PojoAdapter.of(pojo, rootOid, specificationLoader);
     }
 
-    public static ObjectAdapter createCollectionAdapter(
-            final Object pojo,
-            final @NonNull ParentedOid collectionOid, 
-            final @NonNull SpecificationLoader specificationLoader) {
-        return PojoAdapter.of(pojo, collectionOid, specificationLoader);
-    }
-
-    public static ObjectAdapter createCollectionAdapter(
-            final @NonNull Object pojo,
-            final RootOid parentOid,
-            final OneToManyAssociation otma, 
-            final @NonNull SpecificationLoader specificationLoader) {
-
-        // persistence of collection follows the parent
-        final ParentedOid collectionOid = Oid.Factory.parented(parentOid, otma);
-        return createCollectionAdapter(pojo, collectionOid, specificationLoader);
-    }
+//    public static ObjectAdapter createCollectionAdapter(
+//            final Object pojo,
+//            final @NonNull ParentedOid collectionOid, 
+//            final @NonNull SpecificationLoader specificationLoader) {
+//        return PojoAdapter.of(pojo, collectionOid, specificationLoader);
+//    }
+
+//    private static ObjectAdapter createCollectionAdapter(
+//            final @NonNull Object pojo,
+//            final RootOid parentOid,
+//            final OneToManyAssociation otma, 
+//            final @NonNull SpecificationLoader specificationLoader) {
+//
+//        // persistence of collection follows the parent
+//        final ParentedOid collectionOid = Oid.Factory.parented(parentOid, otma);
+//        return createCollectionAdapter(pojo, collectionOid, specificationLoader);
+//    }
 
     
 }
\ No newline at end of file
diff --git a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/oid/JdoObjectIdSerializer.java b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/oid/JdoObjectIdSerializer.java
index 092517a..99998d0 100644
--- a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/oid/JdoObjectIdSerializer.java
+++ b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/oid/JdoObjectIdSerializer.java
@@ -43,9 +43,7 @@ import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.commons.internal.context._Context;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.metamodel.adapter.oid.RootOid;
-import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
 import org.apache.isis.persistence.jdo.integration.oid._JdoObjectIdDecoder.JdoObjectIdDecodingRequest;
 
 import lombok.NonNull;
@@ -85,12 +83,6 @@ public final class JdoObjectIdSerializer {
             // re-create-able through the constructor
             jdoOid.getClass().getName() + SEPARATOR + jdoOid.toString());
     }
-
-    @Deprecated
-    public static Object toJdoObjectId(SpecificationLoader specificationLoader, RootOid oid) {
-        val spec = specificationLoader.lookupBySpecIdElseLoad(oid.getObjectSpecId());
-        return toJdoObjectId(spec, oid);
-    }
     
     public static Object toJdoObjectId(ObjectSpecification spec, RootOid oid) {
         
diff --git a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/IsisLifecycleListener.java b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/IsisLifecycleListener.java
index e089900..9b38992 100644
--- a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/IsisLifecycleListener.java
+++ b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/IsisLifecycleListener.java
@@ -44,7 +44,6 @@ DetachLifecycleListener, DirtyLifecycleListener, LoadLifecycleListener, StoreLif
      */
     interface PersistenceSessionLifecycleManagement {
 
-        void ensureRootObject(Persistable pojo);
         ObjectAdapter initializeEntity(Persistable pojo);
 
         void invokeIsisPersistingCallback(Persistable pojo);
@@ -75,25 +74,25 @@ DetachLifecycleListener, DirtyLifecycleListener, LoadLifecycleListener, StoreLif
 
     @Override
     public void preAttach(final InstanceLifecycleEvent event) {
-        final Persistable pojo = _Utils.persistenceCapableFor(event);
-        persistenceSession.ensureRootObject(pojo);
+        final Persistable pojo = _Utils.persistableFor(event);
+        _Utils.ensureRootObject(pojo);
     }
 
     @Override
     public void postAttach(final InstanceLifecycleEvent event) {
-        final Persistable pojo = _Utils.persistenceCapableFor(event);
-        persistenceSession.ensureRootObject(pojo);
+        final Persistable pojo = _Utils.persistableFor(event);
+        _Utils.ensureRootObject(pojo);
     }
 
     @Override
     public void postLoad(final InstanceLifecycleEvent event) {
-        final Persistable pojo = _Utils.persistenceCapableFor(event);
+        final Persistable pojo = _Utils.persistableFor(event);
         persistenceSession.initializeEntity(pojo);
     }
 
     @Override
     public void preStore(InstanceLifecycleEvent event) {
-        final Persistable pojo = _Utils.persistenceCapableFor(event);
+        final Persistable pojo = _Utils.persistableFor(event);
         if(pojo.dnGetStateManager().isNew(pojo)) {
             persistenceSession.invokeIsisPersistingCallback(pojo);
         }
@@ -101,7 +100,7 @@ DetachLifecycleListener, DirtyLifecycleListener, LoadLifecycleListener, StoreLif
 
     @Override
     public void postStore(InstanceLifecycleEvent event) {
-        final Persistable pojo = _Utils.persistenceCapableFor(event);
+        final Persistable pojo = _Utils.persistableFor(event);
         if(pojo.dnGetStateManager().isNew(pojo)) {
             persistenceSession.enlistCreatedAndInvokeIsisPersistedCallback(pojo);
         } else {
@@ -111,7 +110,7 @@ DetachLifecycleListener, DirtyLifecycleListener, LoadLifecycleListener, StoreLif
 
     @Override
     public void preDirty(InstanceLifecycleEvent event) {
-        final Persistable pojo = _Utils.persistenceCapableFor(event);
+        final Persistable pojo = _Utils.persistableFor(event);
         persistenceSession.enlistUpdatingAndInvokeIsisUpdatingCallback(pojo);
     }
 
@@ -127,7 +126,7 @@ DetachLifecycleListener, DirtyLifecycleListener, LoadLifecycleListener, StoreLif
 
     @Override
     public void preDelete(InstanceLifecycleEvent event) {
-        final Persistable pojo = _Utils.persistenceCapableFor(event);
+        final Persistable pojo = _Utils.persistableFor(event);
         persistenceSession.enlistDeletingAndInvokeIsisRemovingCallbackFacet(pojo);
 
 
@@ -162,14 +161,14 @@ DetachLifecycleListener, DirtyLifecycleListener, LoadLifecycleListener, StoreLif
 
     @Override
     public void preDetach(InstanceLifecycleEvent event) {
-        final Persistable pojo = _Utils.persistenceCapableFor(event);
-        persistenceSession.ensureRootObject(pojo);
+        final Persistable pojo = _Utils.persistableFor(event);
+        _Utils.ensureRootObject(pojo);
     }
 
     @Override
     public void postDetach(InstanceLifecycleEvent event) {
-        final Persistable pojo = _Utils.persistenceCapableFor(event);
-        persistenceSession.ensureRootObject(pojo);
+        final Persistable pojo = _Utils.persistableFor(event);
+        _Utils.ensureRootObject(pojo);
     }
 
     // /////////////////////////////////////////////////////////
diff --git a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/PersistenceSession.java b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/PersistenceSession.java
index 3022dd2..c49890d 100644
--- a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/PersistenceSession.java
+++ b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/PersistenceSession.java
@@ -19,15 +19,12 @@
 package org.apache.isis.persistence.jdo.integration.persistence;
 
 import java.rmi.NoSuchObjectException;
-import java.util.List;
-import java.util.Map;
 import java.util.Optional;
 
 import org.apache.isis.applib.query.Query;
 import org.apache.isis.applib.services.repository.EntityState;
 import org.apache.isis.applib.services.xactn.TransactionService;
 import org.apache.isis.commons.collections.Can;
-import org.apache.isis.core.metamodel.adapter.oid.RootOid;
 import org.apache.isis.core.metamodel.spec.ManagedObject;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 
@@ -84,9 +81,6 @@ public interface PersistenceSession {
      */
     ManagedObject fetchByIdentifier(ObjectSpecification spec, String identifier);
 
-    /**@since 2.0*/
-    Map<RootOid, Object> fetchPersistentPojos(List<RootOid> rootOids);
-
     Can<ManagedObject> allMatchingQuery(final Query<?> query);
     Optional<ManagedObject> firstMatchingQuery(final Query<?> query);
 
diff --git a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/PersistenceSession5.java b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/PersistenceSession5.java
index d75921e..a20cfef 100644
--- a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/PersistenceSession5.java
+++ b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/PersistenceSession5.java
@@ -19,32 +19,22 @@
 package org.apache.isis.persistence.jdo.integration.persistence;
 
 import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
 import java.util.List;
-import java.util.Map;
 import java.util.Optional;
 
 import javax.annotation.Nullable;
 import javax.enterprise.inject.Vetoed;
 import javax.jdo.FetchGroup;
-import javax.jdo.FetchPlan;
 import javax.jdo.PersistenceManager;
 import javax.jdo.PersistenceManagerFactory;
-import javax.jdo.identity.SingleFieldIdentity;
 
 import org.datanucleus.enhancement.Persistable;
-import org.datanucleus.exceptions.NucleusObjectNotFoundException;
-import org.datanucleus.identity.DatastoreIdImpl;
 
 import org.apache.isis.applib.query.Query;
 import org.apache.isis.applib.services.exceprecog.ExceptionRecognizer;
 import org.apache.isis.applib.services.repository.EntityState;
 import org.apache.isis.applib.services.xactn.TransactionService;
 import org.apache.isis.commons.collections.Can;
-import org.apache.isis.commons.exceptions.IsisException;
-import org.apache.isis.commons.internal.collections._Maps;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.metamodel.adapter.oid.ObjectNotFoundException;
 import org.apache.isis.core.metamodel.adapter.oid.Oid;
@@ -75,8 +65,6 @@ import org.apache.isis.persistence.jdo.integration.persistence.query.Persistence
 import org.apache.isis.persistence.jdo.integration.persistence.query.PersistenceQueryFindAllInstances;
 import org.apache.isis.persistence.jdo.integration.persistence.query.PersistenceQueryFindUsingApplibQueryDefault;
 
-import static org.apache.isis.commons.internal.base._Casts.uncheckedCast;
-
 import lombok.Getter;
 import lombok.NonNull;
 import lombok.val;
@@ -345,6 +333,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
         } catch (final RuntimeException e) {
 
             //XXX this idiom could be delegated to a service
+            //or remodel the method to return a Result<T>
             for (val exceptionRecognizer : lookupServices(ExceptionRecognizer.class)) {
                 val recognition = exceptionRecognizer.recognize(e).orElse(null);
                 if(recognition != null) {
@@ -364,71 +353,71 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
         return result;
     }
 
-    @Override
-    public Map<RootOid,Object> fetchPersistentPojos(final List<RootOid> rootOids) {
-
-        if(rootOids.isEmpty()) {
-            return Collections.emptyMap();
-        }
-
-        val specLoader = super.getSpecificationLoader();
-        
-        final List<Object> dnOids = new ArrayList<>(rootOids.size());
-        for (val rootOid : rootOids) {
-            final Object id = JdoObjectIdSerializer.toJdoObjectId(specLoader, rootOid);
-            if(id instanceof SingleFieldIdentity) {
-                dnOids.add(id);
-            } else if (id instanceof String && ((String) id).contains("[OID]")) {
-                final DatastoreIdImpl datastoreId = new DatastoreIdImpl((String)id);
-                dnOids.add(datastoreId);
-            } else {
-                // application identity
-                final DatastoreIdImpl datastoreId = new DatastoreIdImpl(clsOf(rootOid).getName(), id);
-                dnOids.add(datastoreId);
-            }
-        }
-        FetchPlan fetchPlan = persistenceManager.getFetchPlan();
-        fetchPlan.addGroup(FetchGroup.DEFAULT);
-        final List<Object> persistentPojos = new ArrayList<>(rootOids.size());
-        try {
-            final Collection<Object> pojos = uncheckedCast(persistenceManager.getObjectsById(dnOids, true));
-            for (final Object pojo : pojos) {
-                try {
-                    persistentPojos.add(pojo);
-                } catch(Exception ex) {
-                    persistentPojos.add(null);
-                }
-            }
-        } catch(NucleusObjectNotFoundException nonfe) {
-            // at least one not found; fall back to loading one by one
-            for (final Object dnOid : dnOids) {
-                try {
-                    final Object persistentPojo = persistenceManager.getObjectById(dnOid);
-                    persistentPojos.add(persistentPojo);
-                } catch(Exception ex) {
-                    persistentPojos.add(null);
-                }
-            }
-        }
-        Map<RootOid, Object> pojoByOid = zip(rootOids, persistentPojos);
-        return pojoByOid;
-    }
-
-    private static Map<RootOid, Object> zip(final List<RootOid> rootOids, final Collection<Object> pojos) {
-        final Map<RootOid,Object> pojoByOid = _Maps.newLinkedHashMap();
-        int i = 0;
-        for (final Object pojo : pojos) {
-            final RootOid rootOid = rootOids.get(i++);
-            pojoByOid.put(rootOid, pojo);
-        }
-        return pojoByOid;
-    }
-
-    @Deprecated
-    private Class<?> clsOf(final RootOid oid) {
-        final ObjectSpecification objectSpec = getSpecificationLoader().lookupBySpecIdElseLoad(oid.getObjectSpecId());
-        return objectSpec.getCorrespondingClass();
-    }
+//    @Override
+//    public Map<RootOid,Object> fetchPersistentPojos(final List<RootOid> rootOids) {
+//
+//        if(rootOids.isEmpty()) {
+//            return Collections.emptyMap();
+//        }
+//
+//        val specLoader = super.getSpecificationLoader();
+//        
+//        final List<Object> dnOids = new ArrayList<>(rootOids.size());
+//        for (val rootOid : rootOids) {
+//            final Object id = JdoObjectIdSerializer.toJdoObjectId(specLoader, rootOid);
+//            if(id instanceof SingleFieldIdentity) {
+//                dnOids.add(id);
+//            } else if (id instanceof String && ((String) id).contains("[OID]")) {
+//                final DatastoreIdImpl datastoreId = new DatastoreIdImpl((String)id);
+//                dnOids.add(datastoreId);
+//            } else {
+//                // application identity
+//                final DatastoreIdImpl datastoreId = new DatastoreIdImpl(clsOf(rootOid).getName(), id);
+//                dnOids.add(datastoreId);
+//            }
+//        }
+//        FetchPlan fetchPlan = persistenceManager.getFetchPlan();
+//        fetchPlan.addGroup(FetchGroup.DEFAULT);
+//        final List<Object> persistentPojos = new ArrayList<>(rootOids.size());
+//        try {
+//            final Collection<Object> pojos = uncheckedCast(persistenceManager.getObjectsById(dnOids, true));
+//            for (final Object pojo : pojos) {
+//                try {
+//                    persistentPojos.add(pojo);
+//                } catch(Exception ex) {
+//                    persistentPojos.add(null);
+//                }
+//            }
+//        } catch(NucleusObjectNotFoundException nonfe) {
+//            // at least one not found; fall back to loading one by one
+//            for (final Object dnOid : dnOids) {
+//                try {
+//                    final Object persistentPojo = persistenceManager.getObjectById(dnOid);
+//                    persistentPojos.add(persistentPojo);
+//                } catch(Exception ex) {
+//                    persistentPojos.add(null);
+//                }
+//            }
+//        }
+//        Map<RootOid, Object> pojoByOid = zip(rootOids, persistentPojos);
+//        return pojoByOid;
+//    }
+//
+//    private static Map<RootOid, Object> zip(final List<RootOid> rootOids, final Collection<Object> pojos) {
+//        final Map<RootOid,Object> pojoByOid = _Maps.newLinkedHashMap();
+//        int i = 0;
+//        for (final Object pojo : pojos) {
+//            final RootOid rootOid = rootOids.get(i++);
+//            pojoByOid.put(rootOid, pojo);
+//        }
+//        return pojoByOid;
+//    }
+//
+//    @Deprecated
+//    private Class<?> clsOf(final RootOid oid) {
+//        final ObjectSpecification objectSpec = getSpecificationLoader().lookupBySpecIdElseLoad(oid.getObjectSpecId());
+//        return objectSpec.getCorrespondingClass();
+//    }
 
 
     // -- REFRESH
@@ -661,19 +650,7 @@ implements IsisLifecycleListener.PersistenceSessionLifecycleManagement {
         getEntityChangeTracker().recognizeUpdating(entity);
     }
 
-    /**
-     * makes sure the entity is known to Isis and is a root
-     * @param pojo
-     */
-    @Override
-    public void ensureRootObject(final Persistable pojo) {
-        final Oid oid = adapterFor(pojo).getOid();
-        if (!(oid instanceof RootOid)) {
-            throw new IsisException(MessageFormat.format("Not a RootOid: oid={0}, for {1}", oid, pojo));
-        }
-    }
-
-    @Override
+    @Override //XXX also provided by 'provider' module
     public EntityState getEntityState(@Nullable Object pojo) {
 
         // guard against misuse
diff --git a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/_Utils.java b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/_Utils.java
index 6ffb988..be1a261 100644
--- a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/_Utils.java
+++ b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/_Utils.java
@@ -18,23 +18,42 @@
  */
 package org.apache.isis.persistence.jdo.integration.persistence;
 
+import javax.annotation.Nullable;
 import javax.jdo.listener.InstanceLifecycleEvent;
 
 import org.datanucleus.enhancement.Persistable;
 
+import org.apache.isis.applib.services.inject.ServiceInjector;
+import org.apache.isis.core.metamodel.objectmanager.ObjectManager;
+import org.apache.isis.core.metamodel.spec.ManagedObject;
+import org.apache.isis.core.metamodel.spec.ManagedObjects;
+import org.apache.isis.persistence.jdo.integration.objectadapter.ObjectAdapter;
+import org.apache.isis.persistence.jdo.integration.objectadapter.PojoAdapter;
+
+import lombok.NonNull;
+import lombok.val;
+
 final class _Utils {
 
     @SuppressWarnings("unused")
     private static Object jdoObjectIdFor(InstanceLifecycleEvent event) {
-        Persistable persistenceCapable = _Utils.persistenceCapableFor(event);
+        Persistable persistenceCapable = _Utils.persistableFor(event);
         Object jdoObjectId = persistenceCapable.dnGetObjectId();
         return jdoObjectId;
     }
 
-    static Persistable persistenceCapableFor(InstanceLifecycleEvent event) {
+    static Persistable persistableFor(InstanceLifecycleEvent event) {
         return (Persistable)event.getSource();
     }
     
+    static boolean ensureRootObject(final Persistable pojo) {
+//        final Oid oid = adapterFor(pojo).getOid();
+//        if (!(oid instanceof RootOid)) {
+//            throw new IsisException(MessageFormat.format("Not a RootOid: oid={0}, for {1}", oid, pojo));
+//        }
+        return pojo!=null; // why would a Persistable ever be something different?
+    }
+    
     static boolean isJUnitTest() {
         for (StackTraceElement element : Thread.currentThread().getStackTrace()) {
             if (element.getClassName().startsWith("org.junit.")) {
@@ -44,4 +63,42 @@ final class _Utils {
         return false;
     }
 
+    // -- LOW LEVEL
+    
+    @Nullable
+    static ObjectAdapter adapterFor(
+            final @NonNull ObjectManager objectManager, 
+            final @Nullable Object pojo) {
+
+        if(pojo == null) {
+            return null;
+        }
+
+        val adapter = objectManager.adapt(pojo);
+        val rootOid = objectManager.identifyObject(adapter);
+        val newAdapter = PojoAdapter.of(pojo, rootOid, 
+                objectManager.getMetaModelContext().getSpecificationLoader()); 
+                
+        injectServices(objectManager.getMetaModelContext().getServiceInjector(), newAdapter);
+        return newAdapter;
+    }
+    
+    @Nullable
+    static ManagedObject injectServices(
+            final @NonNull ServiceInjector serviceInjector,
+            final @Nullable ManagedObject adapter) {
+        
+        if(ManagedObjects.isNullOrUnspecifiedOrEmpty(adapter)) {
+            return adapter; 
+        }
+        
+        val spec = adapter.getSpecification();
+        if(spec==null 
+                || spec.isValue()) {
+            return adapter; // guard against value objects
+        }
+        serviceInjector.injectServicesInto(adapter.getPojo());
+        return adapter;
+    }
+    
 }
diff --git a/persistence/jdo/integration/src/test/java/org/apache/isis/persistence/jdo/integration/testing/PojoAdapterBuilder.java b/persistence/jdo/integration/src/test/java/org/apache/isis/persistence/jdo/integration/testing/PojoAdapterBuilder.java
index 257ee1e..6efece9 100644
--- a/persistence/jdo/integration/src/test/java/org/apache/isis/persistence/jdo/integration/testing/PojoAdapterBuilder.java
+++ b/persistence/jdo/integration/src/test/java/org/apache/isis/persistence/jdo/integration/testing/PojoAdapterBuilder.java
@@ -21,6 +21,7 @@ package org.apache.isis.persistence.jdo.integration.testing;
 import java.util.Iterator;
 
 import org.apache.isis.commons.internal.base._Strings;
+import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.metamodel.adapter.oid.Oid;
 import org.apache.isis.core.metamodel.adapter.oid.Oid.Factory;
 import org.apache.isis.core.metamodel.adapter.oid.RootOid;
@@ -72,7 +73,7 @@ public class PojoAdapterBuilder {
         }, COLLECTION {
             @Override
             Oid oidFor(RootOid rootOid, ObjectSpecId objectSpecId, String collectionId) {
-                return Oid.Factory.parentedForTesting(rootOid, collectionId);
+                throw _Exceptions.illegalArgument("Parented Oids are no longer supported.");
             }
         }, VALUE {
             @Override