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 2021/12/02 16:19:02 UTC

[isis] branch master updated: ISIS-2903: core: use Bookmarks over String identifiers, when possible

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 2f3e963  ISIS-2903: core: use Bookmarks over String identifiers, when possible
2f3e963 is described below

commit 2f3e9631ec802e7598bd4b29df53791edf786836
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Dec 2 17:18:49 2021 +0100

    ISIS-2903: core: use Bookmarks over String identifiers, when possible
    
    - also always memoize Bookmarks after object loading
---
 .../org/apache/isis/commons/internal/debug/_Debug.java   |  9 ++++++---
 .../isis/core/metamodel/context/MetaModelContext.java    | 11 +++++------
 .../core/metamodel/facets/object/entity/EntityFacet.java |  3 ++-
 .../facets/object/entity/_EntityFacetForTesting.java     |  3 ++-
 ...ecreatableObjectFacetForXmlRootElementAnnotation.java |  4 +++-
 .../metamodel/interactions/managed/ManagedProperty.java  |  2 --
 .../identify/ObjectBookmarker_builtinHandlers.java       |  5 +++++
 .../core/metamodel/objectmanager/load/ObjectLoader.java  |  3 ++-
 .../objectmanager/load/ObjectLoader_builtinHandlers.java | 16 ++++++++--------
 .../apache/isis/core/metamodel/spec/ManagedObjects.java  |  2 +-
 .../command/CommandExecutorServiceDefault.java           | 13 ++++++++-----
 .../handlers/DelegatingInvocationHandlerDefault.java     |  6 ++----
 .../ui/component/FullCalendarWithEventHandling.java      |  3 +--
 .../metamodel/facets/entity/JdoEntityFacet.java          |  4 +---
 .../jpa/integration/entity/JpaEntityFacetFactory.java    | 14 ++++++++++----
 .../model/models/interaction/BookmarkedObjectWkt.java    |  3 ++-
 16 files changed, 58 insertions(+), 43 deletions(-)

diff --git a/commons/src/main/java/org/apache/isis/commons/internal/debug/_Debug.java b/commons/src/main/java/org/apache/isis/commons/internal/debug/_Debug.java
index b48f595..c7be464 100644
--- a/commons/src/main/java/org/apache/isis/commons/internal/debug/_Debug.java
+++ b/commons/src/main/java/org/apache/isis/commons/internal/debug/_Debug.java
@@ -70,11 +70,14 @@ public class _Debug {
             _NullSafe.streamAutodetect(x)
             .forEach(element->dump(element, indent+1));
         } else {
-            val suffix = _Strings.padStart("", indent, '-');
-            System.err.printf("%s %s%n", suffix, x);
+            if(indent==0) {
+                System.err.printf("%s%n", x);
+            } else {
+                val suffix = _Strings.padEnd("", indent, '-');
+                System.err.printf("%s %s%n", suffix, x);
+            }
         }
     }
 
 
-
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/context/MetaModelContext.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/context/MetaModelContext.java
index 3590ae3..a9a7610 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/context/MetaModelContext.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/context/MetaModelContext.java
@@ -23,7 +23,7 @@ import java.util.stream.Stream;
 
 import org.springframework.lang.Nullable;
 
-import org.apache.isis.applib.services.bookmark.Oid;
+import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.services.factory.FactoryService;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.applib.services.iactn.InteractionProvider;
@@ -124,17 +124,16 @@ public interface MetaModelContext {
      */
     <T> T getSingletonElseFail(Class<T> type);
 
-    default Optional<ManagedObject> loadObject(final @Nullable Oid oid) {
-        if(oid==null) {
+    default Optional<ManagedObject> loadObject(final @Nullable Bookmark bookmark) {
+        if(bookmark==null) {
             return Optional.empty();
         }
-        val objectId = oid.getIdentifier();
         val specLoader = getSpecificationLoader();
         val objManager = getObjectManager();
         return specLoader
-                .specForLogicalTypeName(oid.getLogicalTypeName())
+                .specForLogicalTypeName(bookmark.getLogicalTypeName())
                 .map(spec->objManager.loadObject(
-                        ObjectLoader.Request.of(spec, objectId)));
+                        ObjectLoader.Request.of(spec, bookmark)));
     }
 
     // -- EXTRACTORS
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/entity/EntityFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/entity/EntityFacet.java
index 095aa13..310c15d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/entity/EntityFacet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/entity/EntityFacet.java
@@ -21,6 +21,7 @@ package org.apache.isis.core.metamodel.facets.object.entity;
 import java.lang.reflect.Method;
 
 import org.apache.isis.applib.query.Query;
+import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.services.repository.EntityState;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.core.metamodel.facetapi.Facet;
@@ -36,7 +37,7 @@ public interface EntityFacet extends Facet {
 
     String identifierFor(ObjectSpecification spec, Object pojo);
 
-    ManagedObject fetchByIdentifier(ObjectSpecification spec, String identifier);
+    ManagedObject fetchByIdentifier(ObjectSpecification spec, Bookmark bookmark);
     Can<ManagedObject> fetchByQuery(ObjectSpecification spec, Query<?> query);
 
     void persist(ObjectSpecification spec, Object pojo);
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/entity/_EntityFacetForTesting.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/entity/_EntityFacetForTesting.java
index 59b32d1..cca3abb 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/entity/_EntityFacetForTesting.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/entity/_EntityFacetForTesting.java
@@ -22,6 +22,7 @@ import java.lang.reflect.Method;
 import java.util.function.BiConsumer;
 
 import org.apache.isis.applib.query.Query;
+import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.services.repository.EntityState;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
@@ -59,7 +60,7 @@ class _EntityFacetForTesting implements EntityFacet {
     }
 
     @Override
-    public ManagedObject fetchByIdentifier(final ObjectSpecification spec, final String identifier) {
+    public ManagedObject fetchByIdentifier(final ObjectSpecification spec, final Bookmark bookmark) {
         throw _Exceptions.unsupportedOperation();
     }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/RecreatableObjectFacetForXmlRootElementAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/RecreatableObjectFacetForXmlRootElementAnnotation.java
index 63729df..7f2dbeb 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/RecreatableObjectFacetForXmlRootElementAnnotation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/recreatable/RecreatableObjectFacetForXmlRootElementAnnotation.java
@@ -47,7 +47,9 @@ extends RecreatableObjectFacetAbstract {
         final String xml = getJaxbService().toXml(vmPojo);
         final String encoded = getUrlEncodingService().encodeString(xml);
         //FIXME[ISIS-2903] gets called about 4 times per same object, why?
-        //System.err.printf("%s%n", encoded);
+//        _Debug.onCondition(true, ()->{
+//            System.err.printf("%s%n", encoded);
+//        });
         return encoded;
     }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ManagedProperty.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ManagedProperty.java
index 44bc880..a454931 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ManagedProperty.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ManagedProperty.java
@@ -25,7 +25,6 @@ import org.springframework.lang.Nullable;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.commons.binding.Observable;
 import org.apache.isis.commons.collections.Can;
-import org.apache.isis.commons.internal.base._Blackhole;
 import org.apache.isis.commons.internal.binding._Observables;
 import org.apache.isis.commons.internal.binding._Observables.LazyObservable;
 import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
@@ -76,7 +75,6 @@ extends ManagedMember {
             final @NonNull Where where) {
         super(owner, where);
         this.property = property;
-        _Blackhole.consume(owner.getBookmark()); // memoize bookmark
         observablePropValue = _Observables.lazy(this::reassessPropertyValue);
     }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/identify/ObjectBookmarker_builtinHandlers.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/identify/ObjectBookmarker_builtinHandlers.java
index 7840e3d..8298d32 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/identify/ObjectBookmarker_builtinHandlers.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/identify/ObjectBookmarker_builtinHandlers.java
@@ -201,6 +201,11 @@ class ObjectBookmarker_builtinHandlers {
 
         @Override
         public Bookmark handle(final ManagedObject managedObject) {
+
+            if(managedObject.isBookmarkMemoized()) {
+                return managedObject.getBookmark().get();
+            }
+
             val spec = managedObject.getSpecification();
             val recreatableObjectFacet = spec.getFacet(ViewModelFacet.class);
             val identifier = recreatableObjectFacet.memento(managedObject.getPojo());
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/load/ObjectLoader.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/load/ObjectLoader.java
index 99cdaf1..331c690 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/load/ObjectLoader.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/load/ObjectLoader.java
@@ -18,6 +18,7 @@
  */
 package org.apache.isis.core.metamodel.objectmanager.load;
 
+import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.commons.handler.ChainOfResponsibility;
 import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.core.metamodel.context.HasMetaModelContext;
@@ -39,7 +40,7 @@ public interface ObjectLoader {
     @Value(staticConstructor = "of")
     public static class Request {
         ObjectSpecification objectSpecification;
-        String objectIdentifier;
+        Bookmark bookmark;
     }
 
     // -- HANDLER
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/load/ObjectLoader_builtinHandlers.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/load/ObjectLoader_builtinHandlers.java
index 9337bf2..5250f9d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/load/ObjectLoader_builtinHandlers.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/load/ObjectLoader_builtinHandlers.java
@@ -160,8 +160,8 @@ final class ObjectLoader_builtinHandlers {
 
             val spec = objectLoadRequest.getObjectSpecification();
 
-            val memento = objectLoadRequest.getObjectIdentifier();
-            val bytes = _Bytes.ofUrlBase64.apply(_Strings.toBytes(memento, StandardCharsets.UTF_8));
+            val bookmark = objectLoadRequest.getBookmark();
+            val bytes = _Bytes.ofUrlBase64.apply(_Strings.toBytes(bookmark.getIdentifier(), StandardCharsets.UTF_8));
             val ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
             val viewModelPojo = ois.readObject();
             ois.close();
@@ -194,16 +194,16 @@ final class ObjectLoader_builtinHandlers {
                         "ObjectSpecification is missing a ViewModelFacet: %s", spec);
             }
 
-            val memento = objectLoadRequest.getObjectIdentifier();
+            val bookmark = objectLoadRequest.getBookmark();
             final Object viewModelPojo;
             if(viewModelFacet.getRecreationMechanism().isInitializes()) {
                 viewModelPojo = this.instantiateAndInjectServices(spec);
-                viewModelFacet.initialize(viewModelPojo, memento);
+                viewModelFacet.initialize(viewModelPojo, bookmark.getIdentifier());
             } else {
-                viewModelPojo = viewModelFacet.instantiate(spec.getCorrespondingClass(), memento);
+                viewModelPojo = viewModelFacet.instantiate(spec.getCorrespondingClass(), bookmark.getIdentifier());
             }
 
-            return ManagedObject.of(spec, viewModelPojo);
+            return ManagedObject.bookmarked(spec, viewModelPojo, bookmark);
         }
 
         private Object instantiateAndInjectServices(final ObjectSpecification spec) {
@@ -258,8 +258,8 @@ final class ObjectLoader_builtinHandlers {
                         "ObjectSpecification is missing an EntityFacet: %s", spec);
             }
 
-            val identifier = objectLoadRequest.getObjectIdentifier();
-            val entity = entityFacet.fetchByIdentifier(spec, identifier);
+            val bookmark = objectLoadRequest.getBookmark();
+            val entity = entityFacet.fetchByIdentifier(spec, bookmark);
             return entity;
         }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObjects.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObjects.java
index d328b65..7c16356 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObjects.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObjects.java
@@ -629,7 +629,7 @@ public final class ManagedObjects {
             .map(bookmark->objectManager.loadObject(
                     ObjectLoader.Request.of(
                                     spec,
-                                    bookmark.getIdentifier())))
+                                    bookmark)))
             .orElse(managedObject);
         }
 
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandExecutorServiceDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandExecutorServiceDefault.java
index 55b1b2c..c6e5689 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandExecutorServiceDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandExecutorServiceDefault.java
@@ -385,18 +385,21 @@ public class CommandExecutorServiceDefault implements CommandExecutorService {
             return ManagedObject.unspecified();
         }
         if(pojo instanceof OidDto) {
-            return adapterForOid(Bookmark.forOidDto((OidDto)pojo));
+            return adapterForBookmark(Bookmark.forOidDto((OidDto)pojo));
+        }
+        if(pojo instanceof Bookmark) {
+            return adapterForBookmark((Bookmark) pojo);
         }
         if(pojo instanceof Oid) {
-            return adapterForOid((Oid) pojo);
+            throw _Exceptions.unexpectedCodeReach();
         }
         // value type
         return ManagedObject.lazy(getSpecificationLoader(), pojo);
     }
 
-    private ManagedObject adapterForOid(final Oid oid) {
-        val spec = specificationLoader.specForLogicalTypeName(oid.getLogicalTypeName()).orElse(null);
-        val loadRequest = ObjectLoader.Request.of(spec, oid.getIdentifier());
+    private ManagedObject adapterForBookmark(final Bookmark bookmark) {
+        val spec = specificationLoader.specForLogicalTypeName(bookmark.getLogicalTypeName()).orElse(null);
+        val loadRequest = ObjectLoader.Request.of(spec, bookmark);
         return spec.getMetaModelContext().getObjectManager().loadObject(loadRequest);
     }
 
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/DelegatingInvocationHandlerDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/DelegatingInvocationHandlerDefault.java
index 40cce0c..e41516b 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/DelegatingInvocationHandlerDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/handlers/DelegatingInvocationHandlerDefault.java
@@ -74,8 +74,6 @@ public class DelegatingInvocationHandlerDefault<T> implements DelegatingInvocati
         }
     }
 
-
-
     protected void resolveIfRequired(final ManagedObject adapter) {
 
         if(!resolveObjectChangedEnabled) {
@@ -88,9 +86,9 @@ public class DelegatingInvocationHandlerDefault<T> implements DelegatingInvocati
             return;
         }
 
-        val oid = objectManager.bookmarkObject(adapter);
+        val bookmark = objectManager.bookmarkObject(adapter);
 
-        val loadRequest = ObjectLoader.Request.of(adapter.getSpecification(), oid.getIdentifier());
+        val loadRequest = ObjectLoader.Request.of(adapter.getSpecification(), bookmark);
 
         objectManager.loadObject(loadRequest);
     }
diff --git a/extensions/vw/fullcalendar/ui/src/main/java/org/apache/isis/extensions/fullcalendar/ui/component/FullCalendarWithEventHandling.java b/extensions/vw/fullcalendar/ui/src/main/java/org/apache/isis/extensions/fullcalendar/ui/component/FullCalendarWithEventHandling.java
index ec94356..3f13cce 100644
--- a/extensions/vw/fullcalendar/ui/src/main/java/org/apache/isis/extensions/fullcalendar/ui/component/FullCalendarWithEventHandling.java
+++ b/extensions/vw/fullcalendar/ui/src/main/java/org/apache/isis/extensions/fullcalendar/ui/component/FullCalendarWithEventHandling.java
@@ -74,8 +74,7 @@ final class FullCalendarWithEventHandling extends FullCalendar {
         final IsisAppCommonContext webAppCommonContext = IsisAppCommonContext.of(metaModelContext);
 
         val spec = specificationLoader.specForLogicalTypeName(bookmark.getLogicalTypeName()).orElse(null);
-        val objectId = bookmark.getIdentifier();
-        val managedObject = objectManager.loadObject(ObjectLoader.Request.of(spec, objectId));
+        val managedObject = objectManager.loadObject(ObjectLoader.Request.of(spec, bookmark));
 
         final EntityModel entityModel = EntityModel.ofAdapter(webAppCommonContext, managedObject);
 
diff --git a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/JdoEntityFacet.java b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/JdoEntityFacet.java
index f7260b3..63c6315 100644
--- a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/JdoEntityFacet.java
+++ b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/JdoEntityFacet.java
@@ -128,12 +128,10 @@ implements EntityFacet {
     @Override
     public ManagedObject fetchByIdentifier(
             final @NonNull ObjectSpecification entitySpec,
-            final @NonNull String identifier) {
+            final @NonNull Bookmark bookmark) {
 
         _Assert.assertTrue(entitySpec.isEntity());
 
-        val bookmark = Bookmark.forLogicalTypeAndIdentifier(entitySpec.getLogicalType(), identifier);
-
         log.debug("fetchEntity; bookmark={}", bookmark);
 
         Object entityPojo;
diff --git a/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/entity/JpaEntityFacetFactory.java b/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/entity/JpaEntityFacetFactory.java
index f75144f..1c289ac 100644
--- a/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/entity/JpaEntityFacetFactory.java
+++ b/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/entity/JpaEntityFacetFactory.java
@@ -33,11 +33,13 @@ import org.apache.isis.applib.exceptions.unrecoverable.ObjectNotFoundException;
 import org.apache.isis.applib.query.AllInstancesQuery;
 import org.apache.isis.applib.query.NamedQuery;
 import org.apache.isis.applib.query.Query;
+import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.services.registry.ServiceRegistry;
 import org.apache.isis.applib.services.repository.EntityState;
 import org.apache.isis.applib.services.urlencoding.UrlEncodingService;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.collections.ImmutableEnumSet;
+import org.apache.isis.commons.internal.assertions._Assert;
 import org.apache.isis.commons.internal.base._Casts;
 import org.apache.isis.commons.internal.base._Lazy;
 import org.apache.isis.commons.internal.base._Strings;
@@ -144,17 +146,21 @@ extends FacetFactoryAbstract {
         @Override
         public ManagedObject fetchByIdentifier(
                 final @NonNull ObjectSpecification entitySpec,
-                final @NonNull String identifier) {
+                final @NonNull Bookmark bookmark) {
 
-            val primaryKey = getObjectIdSerializer().parse(identifier);
+            _Assert.assertTrue(entitySpec.isEntity());
+
+            log.debug("fetchEntity; bookmark={}", bookmark);
+
+            val primaryKey = getObjectIdSerializer().parse(bookmark.getIdentifier());
             val entityManager = getEntityManager();
             val entityPojo = entityManager.find(entityClass, primaryKey);
 
             if (entityPojo == null) {
-                throw new ObjectNotFoundException(""+identifier);
+                throw new ObjectNotFoundException(""+bookmark);
             }
 
-            return ManagedObject.of(entitySpec, entityPojo);
+            return ManagedObject.bookmarked(entitySpec, entityPojo, bookmark);
         }
 
         @Override
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/interaction/BookmarkedObjectWkt.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/interaction/BookmarkedObjectWkt.java
index 6483f61..34c0624 100644
--- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/interaction/BookmarkedObjectWkt.java
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/models/interaction/BookmarkedObjectWkt.java
@@ -135,9 +135,10 @@ extends ModelAbstract<ManagedObject> {
 
     public final ManagedObject getObjectAndAttachWhenEntity() {
         //EntityUtil.assertAttachedWhenEntity()//guard
+        val entityOrViewmodel = super.getObject();
 
         // even though initial loading seems attached, we need to check again
-        return EntityUtil.computeIfDetached(super.getObject(), this::reload);
+        return EntityUtil.computeIfDetached(entityOrViewmodel, this::reload);
     }
 
     @Override