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 d3edaf0511 ISIS-3119: replace all IdStringifiers from applib with 
their value-semantics counterpart
d3edaf0511 is described below

commit d3edaf0511f2c7a13ef9579f1b62780161f9e8db
Author: Andi Huber <[email protected]>
AuthorDate: Thu Aug 11 11:23:02 2022 +0200

    ISIS-3119: replace all IdStringifiers from applib with their
    value-semantics counterpart
---
 .../org/apache/isis/applib/IsisModuleApplib.java   |  21 ----
 .../applib/services/bookmark/IdStringifier.java    |  54 +++++----
 .../idstringifiers/IdStringifierForBigDecimal.java |  45 --------
 .../idstringifiers/IdStringifierForBigInteger.java |  45 --------
 .../idstringifiers/IdStringifierForByte.java       |  45 --------
 .../idstringifiers/IdStringifierForCharacter.java  |  75 ------------
 .../idstringifiers/IdStringifierForInteger.java    |  45 --------
 .../idstringifiers/IdStringifierForLong.java       |  45 --------
 .../IdStringifierForSerializable.java              |  80 -------------
 .../idstringifiers/IdStringifierForShort.java      |  45 --------
 .../idstringifiers/IdStringifierForString.java     |  74 ------------
 .../idstringifiers/IdStringifierForUuid.java       |  46 --------
 .../value/semantics/ValueSemanticsAbstract.java    |   7 ++
 .../value/semantics/ValueSemanticsProvider.java    |   7 +-
 .../ApplicationFeatureIdValueSemantics.java        |   3 +
 .../valuesemantics/BigDecimalValueSemantics.java   |  22 +++-
 .../valuesemantics/BigIntegerValueSemantics.java   |  23 +++-
 .../valuesemantics/BlobValueSemantics.java         |   3 +
 .../valuesemantics/BookmarkValueSemantics.java     |   3 +
 .../valuesemantics/BooleanValueSemantics.java      |   3 +
 .../BufferedImageValueSemantics.java               |   3 +
 .../valuesemantics/ByteValueSemantics.java         |  22 +++-
 .../valuesemantics/ChangesDtoValueSemantics.java   |   3 +
 .../valuesemantics/CharacterValueSemantics.java    |  41 ++++++-
 .../valuesemantics/ClobValueSemantics.java         |   3 +
 .../valuesemantics/CommandDtoValueSemantics.java   |   3 +
 .../valuesemantics/DoubleValueSemantics.java       |   3 +
 .../valuesemantics/FloatValueSemantics.java        |   3 +
 .../valuesemantics/IntValueSemantics.java          |  22 +++-
 .../InteractionDtoValueSemantics.java              |   3 +
 .../LocalResourcePathValueSemantics.java           |   3 +
 .../valuesemantics/LocaleValueSemantics.java       |   3 +
 .../valuesemantics/LongValueSemantics.java         |  22 +++-
 .../valuesemantics/MarkupValueSemantics.java       |   3 +
 .../valuesemantics/OidDtoValueSemantics.java       |   3 +
 .../valuesemantics/PasswordValueSemantics.java     |   3 +
 .../valuesemantics/SerializableValueSemantics.java | 126 +++++++++++++++++++++
 .../valuesemantics/ShortValueSemantics.java        |  22 +++-
 .../valuesemantics/StringValueSemantics.java       |  40 ++++++-
 .../valuesemantics/TreeNodeValueSemantics.java     |   3 +
 .../valuesemantics/URLValueSemantics.java          |   3 +
 .../valuesemantics/UUIDValueSemantics.java         |  20 +++-
 .../IdStringifierForBigDecimal_Test.java           |   8 +-
 .../IdStringifierForBigInteger_Test.java           |  10 +-
 .../valuesemantics}/IdStringifierForByte_Test.java |   8 +-
 .../IdStringifierForByte_primitive_Test.java       |   8 +-
 .../IdStringifierForCharacter_Test.java            |   8 +-
 .../IdStringifierForInteger_Test.java              |   8 +-
 .../IdStringifierForInteger_primitive_Test.java    |   8 +-
 .../valuesemantics}/IdStringifierForLong_Test.java |   8 +-
 .../IdStringifierForLong_primitive_Test.java       |   8 +-
 .../IdStringifierForSerializable_Test.java         |   5 +-
 .../IdStringifierForShort_Test.java                |   8 +-
 .../IdStringifierForShort_primitive_Test.java      |   8 +-
 .../IdStringifierForString_Test.java               |   8 +-
 .../valuesemantics}/IdStringifierForUuid_Test.java |   8 +-
 .../idstringifier/IdStringifierLookupService.java  |   7 +-
 .../jpa/IsisModuleExtCommandLogPersistenceJpa.java |   2 +-
 .../commandlog/jpa/dom/CommandLogEntryPK.java      |  50 +++++++-
 .../dom/CommandLogEntryPK_Stringifier_Test.java    |   4 +-
 .../facets/entity/IdStringifierForCharId.java      |   5 +-
 .../entity/IdStringifierForCharIdentity.java       |   5 +-
 .../facets/entity/IdStringifierForStringId.java    |   5 +-
 .../entity/IdStringifierForStringIdentity.java     |   5 +-
 .../oid/IdStringifierForCharIdentity_Test.java     |  10 +-
 .../oid/IdStringifierForObjectIdentity_Test.java   |   3 +-
 .../oid/IdStringifierForStringIdentity_Test.java   |   7 +-
 67 files changed, 563 insertions(+), 699 deletions(-)

diff --git 
a/api/applib/src/main/java/org/apache/isis/applib/IsisModuleApplib.java 
b/api/applib/src/main/java/org/apache/isis/applib/IsisModuleApplib.java
index 6fc1c1738d..a3a190364b 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/IsisModuleApplib.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/IsisModuleApplib.java
@@ -37,16 +37,6 @@ import 
org.apache.isis.applib.services.appfeatui.ApplicationTypeMember;
 import org.apache.isis.applib.services.appfeatui.ApplicationTypeProperty;
 import org.apache.isis.applib.services.bookmark.BookmarkHolder_lookup;
 import org.apache.isis.applib.services.bookmark.BookmarkHolder_object;
-import 
org.apache.isis.applib.services.bookmark.idstringifiers.IdStringifierForBigDecimal;
-import 
org.apache.isis.applib.services.bookmark.idstringifiers.IdStringifierForBigInteger;
-import 
org.apache.isis.applib.services.bookmark.idstringifiers.IdStringifierForByte;
-import 
org.apache.isis.applib.services.bookmark.idstringifiers.IdStringifierForCharacter;
-import 
org.apache.isis.applib.services.bookmark.idstringifiers.IdStringifierForInteger;
-import 
org.apache.isis.applib.services.bookmark.idstringifiers.IdStringifierForLong;
-import 
org.apache.isis.applib.services.bookmark.idstringifiers.IdStringifierForSerializable;
-import 
org.apache.isis.applib.services.bookmark.idstringifiers.IdStringifierForShort;
-import 
org.apache.isis.applib.services.bookmark.idstringifiers.IdStringifierForString;
-import 
org.apache.isis.applib.services.bookmark.idstringifiers.IdStringifierForUuid;
 import org.apache.isis.applib.services.clock.ClockService;
 import 
org.apache.isis.applib.services.commanddto.conmap.ContentMappingServiceForCommandDto;
 import 
org.apache.isis.applib.services.commanddto.conmap.ContentMappingServiceForCommandsDto;
@@ -102,17 +92,6 @@ import org.apache.isis.schema.IsisModuleSchema;
     UserMenu.class,
 
     // @Service(s)
-    IdStringifierForByte.class,
-    IdStringifierForLong.class,
-    IdStringifierForInteger.class,
-    IdStringifierForShort.class,
-    IdStringifierForUuid.class,
-    IdStringifierForCharacter.class,
-    IdStringifierForString.class,
-    IdStringifierForBigInteger.class,
-    IdStringifierForBigDecimal.class,
-    IdStringifierForSerializable.class,
-
     CommandDtoProcessorServiceIdentity.class,
     ContentMappingServiceForCommandDto.class,
     ContentMappingServiceForCommandsDto.class,
diff --git 
a/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/IdStringifier.java
 
b/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/IdStringifier.java
index 75a58e8b2d..049b71ce76 100644
--- 
a/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/IdStringifier.java
+++ 
b/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/IdStringifier.java
@@ -22,6 +22,9 @@ package org.apache.isis.applib.services.bookmark;
 
 import org.springframework.util.ClassUtils;
 
+import org.apache.isis.commons.internal.assertions._Assert;
+
+import lombok.Getter;
 import lombok.NonNull;
 import lombok.val;
 
@@ -46,19 +49,24 @@ import lombok.val;
  */
 public interface IdStringifier<T> {
 
-    /**
-     * Whether this {@link IdStringifier} is able to {@link #enstring(Object)} 
or {@link #destring(String, Class)} values
-     * of this type.
-     *
-     * <p>
-     * Even though some implementations also require the owning entity type in 
order to {@link #destring(String, Class)},
-     * we do not consider that as part of this function; we assume that the 
entity type will be provided
-     * when necessary (by the JDO entity facet, in fact).  This is sufficient.
-     * </p>
-     *
-     * @param candidateValueClass
-     */
-    boolean handles(@NonNull Class<?> candidateValueClass);
+    Class<T> getCorrespondingClass();
+
+//    /**
+//     * Whether this {@link IdStringifier} is able to {@link 
#enstring(Object)} or {@link #destring(String, Class)} values
+//     * of this type.
+//     *
+//     * <p>
+//     * Even though some implementations also require the owning entity type 
in order to {@link #destring(String, Class)},
+//     * we do not consider that as part of this function; we assume that the 
entity type will be provided
+//     * when necessary (by the JDO entity facet, in fact).  This is 
sufficient.
+//     * </p>
+//     *
+//     * @param candidateValueClass
+//     */
+    default boolean handles(final @NonNull Class<?> candidateValueClass) {
+        return getCorrespondingClass()
+                
.isAssignableFrom(ClassUtils.resolvePrimitiveIfNecessary(candidateValueClass));
+    }
 
 
     /**
@@ -83,23 +91,27 @@ public interface IdStringifier<T> {
 
     abstract class Abstract<T> implements IdStringifier<T> {
 
-        protected final static char SEPARATOR = '_';
+        public final static char SEPARATOR = '_';
 
         /**
          * eg <code>Integer.class</code>, or JDO-specific 
<code>DatastoreId</code>,
          * or a custom class for application-defined PKs.
          */
-        private final Class<?> resolvedClass;
+        @Getter private final Class<T> correspondingClass;
 
         protected Abstract(
-                final @NonNull Class<T> handledClass) {
-            this.resolvedClass = 
ClassUtils.resolvePrimitiveIfNecessary(handledClass);
+                final @NonNull Class<T> correspondingClass) {
+
+            _Assert.assertFalse(correspondingClass.isPrimitive());
+
+            this.correspondingClass = correspondingClass;
+                    ClassUtils.resolvePrimitiveIfNecessary(correspondingClass);
         }
 
         @Override
-        public boolean handles(final @NonNull Class<?> candidateValueClass) {
-            val reolvedCandidateClass = 
ClassUtils.resolvePrimitiveIfNecessary(candidateValueClass);
-            return resolvedClass.isAssignableFrom(reolvedCandidateClass);
+        public final boolean handles(final @NonNull Class<?> 
candidateValueClass) {
+            return getCorrespondingClass()
+                    
.isAssignableFrom(ClassUtils.resolvePrimitiveIfNecessary(candidateValueClass));
         }
 
         /**
@@ -125,7 +137,7 @@ public interface IdStringifier<T> {
      */
     abstract class AbstractWithPrefix<T> extends Abstract<T> {
 
-        private final String prefix;
+                private final String prefix;
 
         public AbstractWithPrefix(
                 @NonNull final Class<T> handledClass,
diff --git 
a/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/idstringifiers/IdStringifierForBigDecimal.java
 
b/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/idstringifiers/IdStringifierForBigDecimal.java
deleted file mode 100644
index 4034e6e033..0000000000
--- 
a/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/idstringifiers/IdStringifierForBigDecimal.java
+++ /dev/null
@@ -1,45 +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.applib.services.bookmark.idstringifiers;
-
-import java.math.BigDecimal;
-
-import javax.annotation.Priority;
-
-import org.springframework.stereotype.Component;
-
-import org.apache.isis.applib.annotation.PriorityPrecedence;
-import org.apache.isis.applib.services.bookmark.IdStringifier;
-
-import lombok.NonNull;
-
-@Component
-@Priority(PriorityPrecedence.LATE)
-public class IdStringifierForBigDecimal extends 
IdStringifier.Abstract<BigDecimal> {
-
-    public IdStringifierForBigDecimal() {
-        super(BigDecimal.class);
-    }
-
-    @Override
-    public BigDecimal destring(final @NonNull String stringified, @NonNull 
Class<?> targetEntityClass) {
-        return new BigDecimal(stringified);
-    }
-}
diff --git 
a/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/idstringifiers/IdStringifierForBigInteger.java
 
b/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/idstringifiers/IdStringifierForBigInteger.java
deleted file mode 100644
index a26f51535d..0000000000
--- 
a/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/idstringifiers/IdStringifierForBigInteger.java
+++ /dev/null
@@ -1,45 +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.applib.services.bookmark.idstringifiers;
-
-import java.math.BigInteger;
-
-import javax.annotation.Priority;
-
-import org.springframework.stereotype.Component;
-
-import org.apache.isis.applib.annotation.PriorityPrecedence;
-import org.apache.isis.applib.services.bookmark.IdStringifier;
-
-import lombok.NonNull;
-
-@Component
-@Priority(PriorityPrecedence.LATE)
-public class IdStringifierForBigInteger extends 
IdStringifier.Abstract<BigInteger> {
-
-    public IdStringifierForBigInteger() {
-        super(BigInteger.class);
-    }
-
-    @Override
-    public BigInteger destring(final @NonNull String stringified, @NonNull 
Class<?> targetEntityClass) {
-        return new BigInteger(stringified);
-    }
-}
diff --git 
a/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/idstringifiers/IdStringifierForByte.java
 
b/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/idstringifiers/IdStringifierForByte.java
deleted file mode 100644
index 51b6b69d62..0000000000
--- 
a/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/idstringifiers/IdStringifierForByte.java
+++ /dev/null
@@ -1,45 +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.applib.services.bookmark.idstringifiers;
-
-import javax.annotation.Priority;
-
-import org.springframework.stereotype.Component;
-
-import org.apache.isis.applib.annotation.PriorityPrecedence;
-import org.apache.isis.applib.services.bookmark.IdStringifier;
-
-import lombok.NonNull;
-
-@Component
-@Priority(PriorityPrecedence.LATE)
-public class IdStringifierForByte extends IdStringifier.Abstract<Byte> {
-
-    public IdStringifierForByte() {
-        super(Byte.class);
-    }
-
-    @Override
-    public Byte destring(
-            final @NonNull String stringified,
-            final @NonNull Class<?> targetEntityClass) {
-        return Byte.parseByte(stringified);
-    }
-}
diff --git 
a/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/idstringifiers/IdStringifierForCharacter.java
 
b/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/idstringifiers/IdStringifierForCharacter.java
deleted file mode 100644
index 144611eef3..0000000000
--- 
a/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/idstringifiers/IdStringifierForCharacter.java
+++ /dev/null
@@ -1,75 +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.applib.services.bookmark.idstringifiers;
-
-import java.util.List;
-import java.util.Objects;
-import java.util.stream.Collectors;
-
-import javax.annotation.Priority;
-
-import org.springframework.stereotype.Component;
-
-import org.apache.isis.applib.annotation.PriorityPrecedence;
-import org.apache.isis.applib.services.bookmark.IdStringifier;
-import org.apache.isis.commons.internal.base._Strings;
-
-import lombok.NonNull;
-
-@Component
-@Priority(PriorityPrecedence.LATE)
-public class IdStringifierForCharacter extends 
IdStringifier.Abstract<Character> {
-
-    public IdStringifierForCharacter() {
-        super(Character.class);
-    }
-
-    static final List<Character> NON_SAFE_URL_CHARS = 
IdStringifierForString.NON_SAFE_URL_CHARS.stream().map(x -> 
x.charAt(0)).collect(Collectors.toList());
-    static final String REGULAR_PREFIX = "c" + SEPARATOR;
-    static final String BASE64_PREFIX = "cbse64" + SEPARATOR;
-
-    /**
-     * Not API, but publicly visible for adhoc reuse by other {@link 
IdStringifier} implementations.
-     */
-    @Override
-    public String enstring(final @NonNull Character id) {
-        if(NON_SAFE_URL_CHARS.stream().anyMatch(x -> Objects.equals(x, id))) {
-            return BASE64_PREFIX + _Strings.base64UrlEncode(""+id);
-        }
-        return REGULAR_PREFIX + id;
-    }
-
-    /**
-     * Not API, but publicly visible for adhoc reuse by other {@link 
IdStringifier} implementations.
-     */
-    @Override
-    public Character destring(
-            final @NonNull String stringified,
-            final @NonNull Class<?> targetEntityClass) {
-        if(stringified.startsWith(REGULAR_PREFIX)) {
-            return stringified.substring(REGULAR_PREFIX.length()).charAt(0);
-        }
-        if(stringified.startsWith(BASE64_PREFIX)) {
-            return 
_Strings.base64UrlDecode(stringified.substring(BASE64_PREFIX.length())).charAt(0);
-        }
-        throw new IllegalArgumentException("Could not parse '" + stringified + 
"'");
-    }
-
-}
diff --git 
a/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/idstringifiers/IdStringifierForInteger.java
 
b/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/idstringifiers/IdStringifierForInteger.java
deleted file mode 100644
index e1ec5ab890..0000000000
--- 
a/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/idstringifiers/IdStringifierForInteger.java
+++ /dev/null
@@ -1,45 +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.applib.services.bookmark.idstringifiers;
-
-import javax.annotation.Priority;
-
-import org.springframework.stereotype.Component;
-
-import org.apache.isis.applib.annotation.PriorityPrecedence;
-import org.apache.isis.applib.services.bookmark.IdStringifier;
-
-import lombok.NonNull;
-
-@Component
-@Priority(PriorityPrecedence.LATE)
-public class IdStringifierForInteger extends IdStringifier.Abstract<Integer> {
-
-    public IdStringifierForInteger() {
-        super(Integer.class);
-    }
-
-    @Override
-    public Integer destring(
-            final @NonNull String stringified,
-            final @NonNull Class<?> targetEntityClass) {
-        return Integer.parseInt(stringified);
-    }
-}
diff --git 
a/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/idstringifiers/IdStringifierForLong.java
 
b/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/idstringifiers/IdStringifierForLong.java
deleted file mode 100644
index 73dddbce29..0000000000
--- 
a/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/idstringifiers/IdStringifierForLong.java
+++ /dev/null
@@ -1,45 +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.applib.services.bookmark.idstringifiers;
-
-import javax.annotation.Priority;
-
-import org.springframework.stereotype.Component;
-
-import org.apache.isis.applib.annotation.PriorityPrecedence;
-import org.apache.isis.applib.services.bookmark.IdStringifier;
-
-import lombok.NonNull;
-
-@Component
-@Priority(PriorityPrecedence.LATE)
-public class IdStringifierForLong extends IdStringifier.Abstract<Long> {
-
-    public IdStringifierForLong() {
-        super(Long.class);
-    }
-
-    @Override
-    public Long destring(
-            final @NonNull String stringified,
-            final @NonNull Class<?> targetEntityClass) {
-        return Long.parseLong(stringified);
-    }
-}
diff --git 
a/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/idstringifiers/IdStringifierForSerializable.java
 
b/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/idstringifiers/IdStringifierForSerializable.java
deleted file mode 100644
index a1507facc9..0000000000
--- 
a/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/idstringifiers/IdStringifierForSerializable.java
+++ /dev/null
@@ -1,80 +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.applib.services.bookmark.idstringifiers;
-
-import java.io.Serializable;
-
-import javax.annotation.Priority;
-import javax.inject.Inject;
-
-import org.springframework.stereotype.Component;
-
-import org.apache.isis.applib.annotation.PriorityPrecedence;
-import org.apache.isis.applib.services.bookmark.IdStringifier;
-import org.apache.isis.applib.services.urlencoding.UrlEncodingService;
-import org.apache.isis.commons.internal.base._Strings;
-import org.apache.isis.commons.internal.resources._Serializables;
-
-import lombok.NonNull;
-
-@Component
-@Priority(PriorityPrecedence.LAST) // goes last - is also enforced by 
IdStringifierLookupService programmatically
-public class IdStringifierForSerializable extends 
IdStringifier.Abstract<Serializable> {
-
-    private final UrlEncodingService codec;
-
-    @Inject
-    public IdStringifierForSerializable(
-            final @NonNull UrlEncodingService codec) {
-        super(Serializable.class);
-        this.codec = codec;
-    }
-
-    @Override
-    public boolean handles(final @NonNull Class<?> candidateValueClass) {
-        return Serializable.class.isAssignableFrom(candidateValueClass);
-    }
-
-    @Override
-    public String enstring(final @NonNull Serializable id) {
-        // even though null case is guarded by lombok - keep null check for 
symmetry
-        return id != null
-                ? codec.encode(_Serializables.write(id))
-                : null;
-    }
-
-    @Override
-    public Serializable destring(
-            final @NonNull String stringified,
-            final @NonNull Class<?> targetEntityClass) {
-        return destringAs(stringified, Serializable.class);
-    }
-
-    // -- HELPER
-
-    private <T extends Serializable> T destringAs(
-            final @NonNull String stringified,
-            final @NonNull Class<T> requiredClass) {
-        return _Strings.isNotEmpty(stringified)
-                ? _Serializables.read(requiredClass, codec.decode(stringified))
-                : null;
-    }
-
-}
diff --git 
a/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/idstringifiers/IdStringifierForShort.java
 
b/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/idstringifiers/IdStringifierForShort.java
deleted file mode 100644
index 99f6d7125d..0000000000
--- 
a/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/idstringifiers/IdStringifierForShort.java
+++ /dev/null
@@ -1,45 +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.applib.services.bookmark.idstringifiers;
-
-import javax.annotation.Priority;
-
-import org.springframework.stereotype.Component;
-
-import org.apache.isis.applib.annotation.PriorityPrecedence;
-import org.apache.isis.applib.services.bookmark.IdStringifier;
-
-import lombok.NonNull;
-
-@Component
-@Priority(PriorityPrecedence.LATE)
-public class IdStringifierForShort extends IdStringifier.Abstract<Short> {
-
-    public IdStringifierForShort() {
-        super(Short.class);
-    }
-
-    @Override
-    public Short destring(
-            final @NonNull String stringified,
-            final @NonNull Class<?> targetEntityClass) {
-        return Short.parseShort(stringified);
-    }
-}
diff --git 
a/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/idstringifiers/IdStringifierForString.java
 
b/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/idstringifiers/IdStringifierForString.java
deleted file mode 100644
index 66774f9193..0000000000
--- 
a/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/idstringifiers/IdStringifierForString.java
+++ /dev/null
@@ -1,74 +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.applib.services.bookmark.idstringifiers;
-
-import java.util.Arrays;
-import java.util.List;
-
-import javax.annotation.Priority;
-
-import org.springframework.stereotype.Component;
-
-import org.apache.isis.applib.annotation.PriorityPrecedence;
-import org.apache.isis.applib.services.bookmark.IdStringifier;
-import org.apache.isis.commons.internal.base._Strings;
-
-import lombok.NonNull;
-
-@Component
-@Priority(PriorityPrecedence.LATE)
-public class IdStringifierForString extends IdStringifier.Abstract<String> {
-
-    public IdStringifierForString() {
-        super(String.class);
-    }
-
-    static final List<String> NON_SAFE_URL_CHARS = Arrays.asList("/", "\\", 
"?", ":", "&", "%", "+");
-    static final String REGULAR_PREFIX = "s" + SEPARATOR;
-    static final String BASE64_PREFIX = "base64" + SEPARATOR;
-
-    /**
-     * Not API, but publicly visible for adhoc reuse by other {@link 
IdStringifier} implementations.
-     */
-    @Override
-    public String enstring(final @NonNull String id) {
-        if(NON_SAFE_URL_CHARS.stream().anyMatch(id::contains)) {
-            return BASE64_PREFIX + _Strings.base64UrlEncode(id);
-        }
-        return REGULAR_PREFIX + id;
-    }
-
-    /**
-     * Not API, but publicly visible for adhoc reuse by other {@link 
IdStringifier} implementations.
-     */
-    @Override
-    public String destring(
-            final @NonNull String stringified,
-            final @NonNull Class<?> targetEntityClass) {
-        if(stringified.startsWith(REGULAR_PREFIX)) {
-            return stringified.substring(REGULAR_PREFIX.length());
-        }
-        if(stringified.startsWith(BASE64_PREFIX)) {
-            return 
_Strings.base64UrlDecode(stringified.substring(BASE64_PREFIX.length()));
-        }
-        throw new IllegalArgumentException(String.format("Could not parse 
'%s'", stringified));
-    }
-
-}
diff --git 
a/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/idstringifiers/IdStringifierForUuid.java
 
b/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/idstringifiers/IdStringifierForUuid.java
deleted file mode 100644
index 6bfb0fbf50..0000000000
--- 
a/api/applib/src/main/java/org/apache/isis/applib/services/bookmark/idstringifiers/IdStringifierForUuid.java
+++ /dev/null
@@ -1,46 +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.applib.services.bookmark.idstringifiers;
-
-import java.util.UUID;
-
-import javax.annotation.Priority;
-
-import org.springframework.stereotype.Component;
-
-import org.apache.isis.applib.annotation.PriorityPrecedence;
-import org.apache.isis.applib.services.bookmark.IdStringifier;
-
-import lombok.NonNull;
-
-@Component
-@Priority(PriorityPrecedence.LATE)
-public class IdStringifierForUuid extends IdStringifier.Abstract<UUID> {
-
-    public IdStringifierForUuid() {
-        super(UUID.class);
-    }
-
-    @Override
-    public UUID destring(final @NonNull String stringified, @NonNull Class<?> 
targetEntityClass) {
-        return UUID.fromString(stringified);
-    }
-
-}
diff --git 
a/api/applib/src/main/java/org/apache/isis/applib/value/semantics/ValueSemanticsAbstract.java
 
b/api/applib/src/main/java/org/apache/isis/applib/value/semantics/ValueSemanticsAbstract.java
index 8a91c3aada..e3b1c1172d 100644
--- 
a/api/applib/src/main/java/org/apache/isis/applib/value/semantics/ValueSemanticsAbstract.java
+++ 
b/api/applib/src/main/java/org/apache/isis/applib/value/semantics/ValueSemanticsAbstract.java
@@ -39,6 +39,7 @@ import org.springframework.lang.Nullable;
 import org.apache.isis.applib.annotation.TimePrecision;
 import org.apache.isis.applib.exceptions.recoverable.TextEntryParseException;
 import org.apache.isis.applib.locale.UserLocale;
+import org.apache.isis.applib.services.bookmark.IdStringifier;
 import org.apache.isis.applib.services.i18n.TranslationContext;
 import org.apache.isis.applib.services.i18n.TranslationService;
 import org.apache.isis.applib.services.iactnlayer.InteractionContext;
@@ -112,6 +113,12 @@ implements
         return this instanceof DefaultsProvider ? (DefaultsProvider<T>)this : 
null;
     }
 
+    @SuppressWarnings("unchecked")
+    @Override
+    public IdStringifier<T> getIdStringifier() {
+        return this instanceof IdStringifier ? (IdStringifier<T>)this : null;
+    }
+
     /**
      * JUnit support.
      */
diff --git 
a/api/applib/src/main/java/org/apache/isis/applib/value/semantics/ValueSemanticsProvider.java
 
b/api/applib/src/main/java/org/apache/isis/applib/value/semantics/ValueSemanticsProvider.java
index a7abf61686..12783b1855 100644
--- 
a/api/applib/src/main/java/org/apache/isis/applib/value/semantics/ValueSemanticsProvider.java
+++ 
b/api/applib/src/main/java/org/apache/isis/applib/value/semantics/ValueSemanticsProvider.java
@@ -23,6 +23,7 @@ import org.springframework.lang.Nullable;
 
 import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.annotation.Value;
+import org.apache.isis.applib.services.bookmark.IdStringifier;
 import org.apache.isis.applib.services.iactnlayer.InteractionContext;
 import org.apache.isis.commons.internal.base._Casts;
 import org.apache.isis.schema.chg.v2.ChangesDto;
@@ -107,12 +108,16 @@ public interface ValueSemanticsProvider<T> {
 
     /**
      * The {@link DefaultsProvider}, if any.
-     *
      * <p>
      * If not <tt>null</tt>, implies that the value has (or may have) a 
default.
      */
     DefaultsProvider<T> getDefaultsProvider();
 
+    /**
+     * The {@link IdStringifier}, if any.
+     */
+    IdStringifier<T> getIdStringifier();
+
     // -- UTILITY
 
     default <X> ValueSemanticsProvider<X> castTo(final Class<X> cls) {
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/ApplicationFeatureIdValueSemantics.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/ApplicationFeatureIdValueSemantics.java
index 4e2b0267ae..d0c6b837e2 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/ApplicationFeatureIdValueSemantics.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/ApplicationFeatureIdValueSemantics.java
@@ -18,10 +18,12 @@
  */
 package org.apache.isis.core.metamodel.valuesemantics;
 
+import javax.annotation.Priority;
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
+import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
 import org.apache.isis.applib.value.semantics.Parser;
 import org.apache.isis.applib.value.semantics.Renderer;
@@ -36,6 +38,7 @@ import lombok.val;
 
 @Component
 @Named("isis.val.ApplicationFeatureIdValueSemantics")
+@Priority(PriorityPrecedence.LATE)
 public class ApplicationFeatureIdValueSemantics
 extends ValueSemanticsAbstract<ApplicationFeatureId>
 implements
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/BigDecimalValueSemantics.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/BigDecimalValueSemantics.java
index 053691b466..d4c4b13495 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/BigDecimalValueSemantics.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/BigDecimalValueSemantics.java
@@ -22,11 +22,14 @@ import java.math.BigDecimal;
 import java.text.DecimalFormat;
 import java.util.function.UnaryOperator;
 
+import javax.annotation.Priority;
 import javax.inject.Inject;
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
+import org.apache.isis.applib.annotation.PriorityPrecedence;
+import org.apache.isis.applib.services.bookmark.IdStringifier;
 import org.apache.isis.applib.value.semantics.DefaultsProvider;
 import org.apache.isis.applib.value.semantics.Parser;
 import org.apache.isis.applib.value.semantics.Renderer;
@@ -39,17 +42,20 @@ import 
org.apache.isis.core.metamodel.specloader.SpecificationLoader;
 import org.apache.isis.schema.common.v2.ValueType;
 import org.apache.isis.schema.common.v2.ValueWithTypeDto;
 
+import lombok.NonNull;
 import lombok.Setter;
 import lombok.val;
 
 @Component
 @Named("isis.val.BigDecimalValueSemantics")
+@Priority(PriorityPrecedence.LATE)
 public class BigDecimalValueSemantics
 extends ValueSemanticsAbstract<BigDecimal>
 implements
     DefaultsProvider<BigDecimal>,
     Parser<BigDecimal>,
-    Renderer<BigDecimal> {
+    Renderer<BigDecimal>,
+    IdStringifier<BigDecimal> {
 
     @Setter @Inject
     private SpecificationLoader specificationLoader;
@@ -82,6 +88,20 @@ implements
                 decomposition, ValueWithTypeDto::getBigDecimal, 
UnaryOperator.identity(), ()->null);
     }
 
+    // -- ID STRINGIFIER
+
+    @Override
+    public String enstring(final @NonNull BigDecimal value) {
+        return value.toString();
+    }
+
+    @Override
+    public BigDecimal destring(
+            final @NonNull String stringified,
+            final @NonNull Class<?> targetEntityClass) {
+        return new BigDecimal(stringified);
+    }
+
     // -- RENDERER
 
     @Override
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/BigIntegerValueSemantics.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/BigIntegerValueSemantics.java
index ac973bccfc..e93648d9a2 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/BigIntegerValueSemantics.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/BigIntegerValueSemantics.java
@@ -21,10 +21,13 @@ package org.apache.isis.core.metamodel.valuesemantics;
 import java.math.BigInteger;
 import java.util.function.UnaryOperator;
 
+import javax.annotation.Priority;
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
+import org.apache.isis.applib.annotation.PriorityPrecedence;
+import org.apache.isis.applib.services.bookmark.IdStringifier;
 import org.apache.isis.applib.value.semantics.DefaultsProvider;
 import org.apache.isis.applib.value.semantics.Parser;
 import org.apache.isis.applib.value.semantics.Renderer;
@@ -34,14 +37,18 @@ import org.apache.isis.commons.collections.Can;
 import org.apache.isis.schema.common.v2.ValueType;
 import org.apache.isis.schema.common.v2.ValueWithTypeDto;
 
+import lombok.NonNull;
+
 @Component
 @Named("isis.val.BigIntegerValueSemantics")
+@Priority(PriorityPrecedence.LATE)
 public class BigIntegerValueSemantics
 extends ValueSemanticsAbstract<BigInteger>
 implements
     DefaultsProvider<BigInteger>,
     Parser<BigInteger>,
-    Renderer<BigInteger> {
+    Renderer<BigInteger>,
+    IdStringifier<BigInteger> {
 
     @Override
     public Class<BigInteger> getCorrespondingClass() {
@@ -83,6 +90,20 @@ implements
         return renderHtml(value, getNumberFormat(context)::format);
     }
 
+    // -- ID STRINGIFIER
+
+    @Override
+    public String enstring(final @NonNull BigInteger value) {
+        return value.toString();
+    }
+
+    @Override
+    public BigInteger destring(
+            final @NonNull String stringified,
+            final @NonNull Class<?> targetEntityClass) {
+        return new BigInteger(stringified);
+    }
+
     // -- PARSER
 
     @Override
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/BlobValueSemantics.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/BlobValueSemantics.java
index f63d474502..08eb32ac7d 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/BlobValueSemantics.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/BlobValueSemantics.java
@@ -20,10 +20,12 @@ package org.apache.isis.core.metamodel.valuesemantics;
 
 import java.util.function.UnaryOperator;
 
+import javax.annotation.Priority;
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
+import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.util.schema.CommonDtoUtils;
 import org.apache.isis.applib.value.Blob;
 import org.apache.isis.applib.value.NamedWithMimeType.CommonMimeType;
@@ -36,6 +38,7 @@ import org.apache.isis.schema.common.v2.ValueType;
 
 @Component
 @Named("isis.val.BlobValueSemantics")
+@Priority(PriorityPrecedence.LATE)
 public class BlobValueSemantics
 extends ValueSemanticsAbstract<Blob>
 implements
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/BookmarkValueSemantics.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/BookmarkValueSemantics.java
index 3487af6910..f25eb63eb9 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/BookmarkValueSemantics.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/BookmarkValueSemantics.java
@@ -18,10 +18,12 @@
  */
 package org.apache.isis.core.metamodel.valuesemantics;
 
+import javax.annotation.Priority;
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
+import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.value.semantics.OrderRelation;
 import org.apache.isis.applib.value.semantics.Parser;
@@ -37,6 +39,7 @@ import lombok.val;
 
 @Component
 @Named("isis.val.BookmarkValueSemantics")
+@Priority(PriorityPrecedence.LATE)
 public class BookmarkValueSemantics
 extends ValueSemanticsAbstract<Bookmark>
 implements
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/BooleanValueSemantics.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/BooleanValueSemantics.java
index da452beb80..7c3bbbfe87 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/BooleanValueSemantics.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/BooleanValueSemantics.java
@@ -20,10 +20,12 @@ package org.apache.isis.core.metamodel.valuesemantics;
 
 import java.util.function.UnaryOperator;
 
+import javax.annotation.Priority;
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
+import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.exceptions.recoverable.TextEntryParseException;
 import org.apache.isis.applib.value.semantics.DefaultsProvider;
 import org.apache.isis.applib.value.semantics.Parser;
@@ -43,6 +45,7 @@ import lombok.val;
  */
 @Component
 @Named("isis.val.BooleanValueSemantics")
+@Priority(PriorityPrecedence.LATE)
 public class BooleanValueSemantics
 extends ValueSemanticsAbstract<Boolean>
 implements
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/BufferedImageValueSemantics.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/BufferedImageValueSemantics.java
index c2051e95c3..70817d1afd 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/BufferedImageValueSemantics.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/BufferedImageValueSemantics.java
@@ -21,11 +21,13 @@ package org.apache.isis.core.metamodel.valuesemantics;
 import java.awt.image.BufferedImage;
 import java.util.Optional;
 
+import javax.annotation.Priority;
 import javax.inject.Named;
 
 import org.springframework.lang.Nullable;
 import org.springframework.stereotype.Component;
 
+import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.value.Blob;
 import org.apache.isis.applib.value.NamedWithMimeType.CommonMimeType;
 import org.apache.isis.applib.value.semantics.OrderRelation;
@@ -41,6 +43,7 @@ import org.apache.isis.schema.common.v2.ValueWithTypeDto;
 
 @Component
 @Named("isis.val.BufferedImageValueSemantics")
+@Priority(PriorityPrecedence.LATE)
 public class BufferedImageValueSemantics
 extends ValueSemanticsAbstract<BufferedImage>
 implements
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/ByteValueSemantics.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/ByteValueSemantics.java
index d6240bbb43..be758b969c 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/ByteValueSemantics.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/ByteValueSemantics.java
@@ -21,11 +21,14 @@ package org.apache.isis.core.metamodel.valuesemantics;
 import java.math.BigInteger;
 import java.util.function.UnaryOperator;
 
+import javax.annotation.Priority;
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
+import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.exceptions.recoverable.TextEntryParseException;
+import org.apache.isis.applib.services.bookmark.IdStringifier;
 import org.apache.isis.applib.value.semantics.DefaultsProvider;
 import org.apache.isis.applib.value.semantics.Parser;
 import org.apache.isis.applib.value.semantics.Renderer;
@@ -36,6 +39,7 @@ import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.schema.common.v2.ValueType;
 import org.apache.isis.schema.common.v2.ValueWithTypeDto;
 
+import lombok.NonNull;
 import lombok.val;
 
 /**
@@ -43,12 +47,14 @@ import lombok.val;
  */
 @Component
 @Named("isis.val.ByteValueSemantics")
+@Priority(PriorityPrecedence.LATE)
 public class ByteValueSemantics
 extends ValueSemanticsAbstract<Byte>
 implements
     DefaultsProvider<Byte>,
     Parser<Byte>,
-    Renderer<Byte> {
+    Renderer<Byte>,
+    IdStringifier<Byte> {
 
     @Override
     public Class<Byte> getCorrespondingClass() {
@@ -78,6 +84,20 @@ implements
                 decomposition, ValueWithTypeDto::getByte, 
UnaryOperator.identity(), ()->null);
     }
 
+    // -- ID STRINGIFIER
+
+    @Override
+    public String enstring(final @NonNull Byte value) {
+        return value.toString();
+    }
+
+    @Override
+    public Byte destring(
+            final @NonNull String stringified,
+            final @NonNull Class<?> targetEntityClass) {
+        return Byte.parseByte(stringified);
+    }
+
     // -- RENDERER
 
     @Override
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/ChangesDtoValueSemantics.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/ChangesDtoValueSemantics.java
index 64f3436ed6..42a7775f08 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/ChangesDtoValueSemantics.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/ChangesDtoValueSemantics.java
@@ -18,16 +18,19 @@
  */
 package org.apache.isis.core.metamodel.valuesemantics;
 
+import javax.annotation.Priority;
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
+import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.util.schema.ChangesDtoUtils;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.schema.chg.v2.ChangesDto;
 
 @Component
 @Named("isis.val.ChangesDtoValueSemantics")
+@Priority(PriorityPrecedence.LATE)
 public class ChangesDtoValueSemantics
 extends XmlValueSemanticsAbstract<ChangesDto> {
 
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/CharacterValueSemantics.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/CharacterValueSemantics.java
index ffe0cbdc3e..ba5366247c 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/CharacterValueSemantics.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/CharacterValueSemantics.java
@@ -18,13 +18,19 @@
  */
 package org.apache.isis.core.metamodel.valuesemantics;
 
+import java.util.List;
+import java.util.Objects;
 import java.util.function.UnaryOperator;
+import java.util.stream.Collectors;
 
+import javax.annotation.Priority;
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
+import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.exceptions.recoverable.InvalidEntryException;
+import org.apache.isis.applib.services.bookmark.IdStringifier;
 import org.apache.isis.applib.value.semantics.DefaultsProvider;
 import org.apache.isis.applib.value.semantics.Parser;
 import org.apache.isis.applib.value.semantics.Renderer;
@@ -35,6 +41,7 @@ import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.schema.common.v2.ValueDto;
 import org.apache.isis.schema.common.v2.ValueType;
 
+import lombok.NonNull;
 import lombok.val;
 
 /**
@@ -42,12 +49,14 @@ import lombok.val;
  */
 @Component
 @Named("isis.val.CharacterValueSemantics")
+@Priority(PriorityPrecedence.LATE)
 public class CharacterValueSemantics
 extends ValueSemanticsAbstract<Character>
 implements
     DefaultsProvider<Character>,
     Parser<Character>,
-    Renderer<Character> {
+    Renderer<Character>,
+    IdStringifier<Character> {
 
     @Override
     public Class<Character> getCorrespondingClass() {
@@ -84,6 +93,36 @@ implements
                 : null;
     }
 
+    // -- ID STRINGIFIER
+
+    static final List<Character> NON_SAFE_URL_CHARS = 
StringValueSemantics.NON_SAFE_URL_CHARS
+            .stream()
+            .map(x -> x.charAt(0))
+            .collect(Collectors.toList());
+    static final String REGULAR_PREFIX = "c" + 
IdStringifier.AbstractWithPrefix.SEPARATOR;
+    static final String BASE64_PREFIX = "cbse64" + 
IdStringifier.AbstractWithPrefix.SEPARATOR;
+
+    @Override
+    public String enstring(final @NonNull Character id) {
+        if(NON_SAFE_URL_CHARS.stream().anyMatch(x -> Objects.equals(x, id))) {
+            return BASE64_PREFIX + _Strings.base64UrlEncode(""+id);
+        }
+        return REGULAR_PREFIX + id;
+    }
+
+    @Override
+    public Character destring(
+            final @NonNull String stringified,
+            final @NonNull Class<?> targetEntityClass) {
+        if(stringified.startsWith(REGULAR_PREFIX)) {
+            return stringified.substring(REGULAR_PREFIX.length()).charAt(0);
+        }
+        if(stringified.startsWith(BASE64_PREFIX)) {
+            return 
_Strings.base64UrlDecode(stringified.substring(BASE64_PREFIX.length())).charAt(0);
+        }
+        throw new IllegalArgumentException("Could not parse '" + stringified + 
"'");
+    }
+
     // -- RENDERER
 
     @Override
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/ClobValueSemantics.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/ClobValueSemantics.java
index 66088dcdc0..d01826a8ec 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/ClobValueSemantics.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/ClobValueSemantics.java
@@ -20,10 +20,12 @@ package org.apache.isis.core.metamodel.valuesemantics;
 
 import java.util.function.UnaryOperator;
 
+import javax.annotation.Priority;
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
+import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.util.schema.CommonDtoUtils;
 import org.apache.isis.applib.value.Clob;
 import org.apache.isis.applib.value.NamedWithMimeType.CommonMimeType;
@@ -36,6 +38,7 @@ import org.apache.isis.schema.common.v2.ValueType;
 
 @Component
 @Named("isis.val.ClobValueSemantics")
+@Priority(PriorityPrecedence.LATE)
 public class ClobValueSemantics
 extends ValueSemanticsAbstract<Clob>
 implements
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/CommandDtoValueSemantics.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/CommandDtoValueSemantics.java
index 0a759e8594..05976b9fac 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/CommandDtoValueSemantics.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/CommandDtoValueSemantics.java
@@ -18,16 +18,19 @@
  */
 package org.apache.isis.core.metamodel.valuesemantics;
 
+import javax.annotation.Priority;
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
+import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.util.schema.CommandDtoUtils;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.schema.cmd.v2.CommandDto;
 
 @Component
 @Named("isis.val.CommandDtoValueSemantics")
+@Priority(PriorityPrecedence.LATE)
 public class CommandDtoValueSemantics
 extends XmlValueSemanticsAbstract<CommandDto> {
 
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/DoubleValueSemantics.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/DoubleValueSemantics.java
index 569f9bb917..ceb6241fd0 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/DoubleValueSemantics.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/DoubleValueSemantics.java
@@ -20,10 +20,12 @@ package org.apache.isis.core.metamodel.valuesemantics;
 
 import java.util.function.UnaryOperator;
 
+import javax.annotation.Priority;
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
+import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.value.semantics.DefaultsProvider;
 import org.apache.isis.applib.value.semantics.Parser;
 import org.apache.isis.applib.value.semantics.Renderer;
@@ -39,6 +41,7 @@ import org.apache.isis.schema.common.v2.ValueWithTypeDto;
  */
 @Component
 @Named("isis.val.DoubleValueSemantics")
+@Priority(PriorityPrecedence.LATE)
 public class DoubleValueSemantics
 extends ValueSemanticsAbstract<Double>
 implements
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/FloatValueSemantics.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/FloatValueSemantics.java
index d76873b94b..0b914e5ca3 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/FloatValueSemantics.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/FloatValueSemantics.java
@@ -20,10 +20,12 @@ package org.apache.isis.core.metamodel.valuesemantics;
 
 import java.util.function.UnaryOperator;
 
+import javax.annotation.Priority;
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
+import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.value.semantics.DefaultsProvider;
 import org.apache.isis.applib.value.semantics.Parser;
 import org.apache.isis.applib.value.semantics.Renderer;
@@ -39,6 +41,7 @@ import org.apache.isis.schema.common.v2.ValueWithTypeDto;
  */
 @Component
 @Named("isis.val.FloatValueSemantics")
+@Priority(PriorityPrecedence.LATE)
 public class FloatValueSemantics
 extends ValueSemanticsAbstract<Float>
 implements
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/IntValueSemantics.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/IntValueSemantics.java
index ab050fd94c..1e52d8dc26 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/IntValueSemantics.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/IntValueSemantics.java
@@ -21,11 +21,14 @@ package org.apache.isis.core.metamodel.valuesemantics;
 import java.math.BigInteger;
 import java.util.function.UnaryOperator;
 
+import javax.annotation.Priority;
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
+import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.exceptions.recoverable.TextEntryParseException;
+import org.apache.isis.applib.services.bookmark.IdStringifier;
 import org.apache.isis.applib.value.semantics.DefaultsProvider;
 import org.apache.isis.applib.value.semantics.Parser;
 import org.apache.isis.applib.value.semantics.Renderer;
@@ -36,6 +39,7 @@ import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.schema.common.v2.ValueType;
 import org.apache.isis.schema.common.v2.ValueWithTypeDto;
 
+import lombok.NonNull;
 import lombok.val;
 
 /**
@@ -43,12 +47,14 @@ import lombok.val;
  */
 @Component
 @Named("isis.val.IntValueSemantics")
+@Priority(PriorityPrecedence.LATE)
 public class IntValueSemantics
 extends ValueSemanticsAbstract<Integer>
 implements
     DefaultsProvider<Integer>,
     Parser<Integer>,
-    Renderer<Integer> {
+    Renderer<Integer>,
+    IdStringifier<Integer>{
 
     @Override
     public Class<Integer> getCorrespondingClass() {
@@ -78,6 +84,20 @@ implements
                 decomposition, ValueWithTypeDto::getInt, 
UnaryOperator.identity(), ()->null);
     }
 
+    // -- ID STRINGIFIER
+
+    @Override
+    public String enstring(final @NonNull Integer value) {
+        return value.toString();
+    }
+
+    @Override
+    public Integer destring(
+            final @NonNull String stringified,
+            final @NonNull Class<?> targetEntityClass) {
+        return Integer.parseInt(stringified);
+    }
+
     // -- RENDERER
 
     @Override
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/InteractionDtoValueSemantics.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/InteractionDtoValueSemantics.java
index 9ab464929a..09bd2506b4 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/InteractionDtoValueSemantics.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/InteractionDtoValueSemantics.java
@@ -18,16 +18,19 @@
  */
 package org.apache.isis.core.metamodel.valuesemantics;
 
+import javax.annotation.Priority;
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
+import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.util.schema.InteractionDtoUtils;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.schema.ixn.v2.InteractionDto;
 
 @Component
 @Named("isis.val.InteractionDtoValueSemantics")
+@Priority(PriorityPrecedence.LATE)
 public class InteractionDtoValueSemantics
 extends XmlValueSemanticsAbstract<InteractionDto> {
 
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/LocalResourcePathValueSemantics.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/LocalResourcePathValueSemantics.java
index c9af88b0d6..1dd9479387 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/LocalResourcePathValueSemantics.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/LocalResourcePathValueSemantics.java
@@ -20,10 +20,12 @@ package org.apache.isis.core.metamodel.valuesemantics;
 
 import java.nio.file.InvalidPathException;
 
+import javax.annotation.Priority;
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
+import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.value.LocalResourcePath;
 import org.apache.isis.applib.value.semantics.Parser;
 import org.apache.isis.applib.value.semantics.Renderer;
@@ -37,6 +39,7 @@ import lombok.val;
 
 @Component
 @Named("isis.val.LocalResourcePathValueSemantics")
+@Priority(PriorityPrecedence.LATE)
 public class LocalResourcePathValueSemantics
 extends ValueSemanticsAbstract<LocalResourcePath>
 implements
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/LocaleValueSemantics.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/LocaleValueSemantics.java
index 6106603e19..0a30f96cb0 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/LocaleValueSemantics.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/LocaleValueSemantics.java
@@ -20,11 +20,13 @@ package org.apache.isis.core.metamodel.valuesemantics;
 
 import java.util.Locale;
 
+import javax.annotation.Priority;
 import javax.inject.Named;
 
 import org.springframework.lang.Nullable;
 import org.springframework.stereotype.Component;
 
+import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.value.semantics.Parser;
 import org.apache.isis.applib.value.semantics.Renderer;
 import org.apache.isis.applib.value.semantics.ValueDecomposition;
@@ -38,6 +40,7 @@ import lombok.val;
 
 @Component
 @Named("isis.val.LocaleValueSemantics")
+@Priority(PriorityPrecedence.LATE)
 public class LocaleValueSemantics
 extends ValueSemanticsAbstract<Locale>
 implements
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/LongValueSemantics.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/LongValueSemantics.java
index f39a6b1ac2..31d9e60c5a 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/LongValueSemantics.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/LongValueSemantics.java
@@ -21,11 +21,14 @@ package org.apache.isis.core.metamodel.valuesemantics;
 import java.math.BigInteger;
 import java.util.function.UnaryOperator;
 
+import javax.annotation.Priority;
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
+import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.exceptions.recoverable.TextEntryParseException;
+import org.apache.isis.applib.services.bookmark.IdStringifier;
 import org.apache.isis.applib.value.semantics.DefaultsProvider;
 import org.apache.isis.applib.value.semantics.Parser;
 import org.apache.isis.applib.value.semantics.Renderer;
@@ -36,6 +39,7 @@ import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.schema.common.v2.ValueType;
 import org.apache.isis.schema.common.v2.ValueWithTypeDto;
 
+import lombok.NonNull;
 import lombok.val;
 
 /**
@@ -43,12 +47,14 @@ import lombok.val;
  */
 @Component
 @Named("isis.val.LongValueSemantics")
+@Priority(PriorityPrecedence.LATE)
 public class LongValueSemantics
 extends ValueSemanticsAbstract<Long>
 implements
     DefaultsProvider<Long>,
     Parser<Long>,
-    Renderer<Long> {
+    Renderer<Long>,
+    IdStringifier<Long>{
 
     @Override
     public Class<Long> getCorrespondingClass() {
@@ -78,6 +84,20 @@ implements
                 decomposition, ValueWithTypeDto::getLong, 
UnaryOperator.identity(), ()->null);
     }
 
+    // -- ID STRINGIFIER
+
+    @Override
+    public String enstring(final @NonNull Long value) {
+        return value.toString();
+    }
+
+    @Override
+    public Long destring(
+            final @NonNull String stringified,
+            final @NonNull Class<?> targetEntityClass) {
+        return Long.parseLong(stringified);
+    }
+
     // -- RENDERER
 
     @Override
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/MarkupValueSemantics.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/MarkupValueSemantics.java
index a3357b56e3..7314aabbdf 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/MarkupValueSemantics.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/MarkupValueSemantics.java
@@ -18,10 +18,12 @@
  */
 package org.apache.isis.core.metamodel.valuesemantics;
 
+import javax.annotation.Priority;
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
+import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.value.Markup;
 import org.apache.isis.applib.value.semantics.Parser;
 import org.apache.isis.applib.value.semantics.Renderer;
@@ -34,6 +36,7 @@ import org.apache.isis.schema.common.v2.ValueType;
 
 @Component
 @Named("isis.val.MarkupValueSemantics")
+@Priority(PriorityPrecedence.LATE)
 public class MarkupValueSemantics
 extends ValueSemanticsAbstract<Markup>
 implements
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/OidDtoValueSemantics.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/OidDtoValueSemantics.java
index 4768aba091..7112759671 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/OidDtoValueSemantics.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/OidDtoValueSemantics.java
@@ -18,11 +18,13 @@
  */
 package org.apache.isis.core.metamodel.valuesemantics;
 
+import javax.annotation.Priority;
 import javax.inject.Inject;
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
+import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.value.semantics.ValueSemanticsAbstract;
 import org.apache.isis.commons.collections.Can;
@@ -31,6 +33,7 @@ import org.apache.isis.schema.common.v2.OidDto;
 
 @Component
 @Named("isis.val.OidDtoValueSemantics")
+@Priority(PriorityPrecedence.LATE)
 public class OidDtoValueSemantics
 extends ValueSemanticsAdapter<OidDto, Bookmark, Void> {
 
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/PasswordValueSemantics.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/PasswordValueSemantics.java
index 545bfd9a19..6bf34ac020 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/PasswordValueSemantics.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/PasswordValueSemantics.java
@@ -18,10 +18,12 @@
  */
 package org.apache.isis.core.metamodel.valuesemantics;
 
+import javax.annotation.Priority;
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
+import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.value.Password;
 import org.apache.isis.applib.value.semantics.Parser;
 import org.apache.isis.applib.value.semantics.Renderer;
@@ -34,6 +36,7 @@ import org.apache.isis.schema.common.v2.ValueWithTypeDto;
 
 @Component
 @Named("isis.val.PasswordValueSemantics")
+@Priority(PriorityPrecedence.LATE)
 public class PasswordValueSemantics
 extends ValueSemanticsAbstract<Password>
 implements
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/SerializableValueSemantics.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/SerializableValueSemantics.java
new file mode 100644
index 0000000000..527b15920d
--- /dev/null
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/SerializableValueSemantics.java
@@ -0,0 +1,126 @@
+/*
+ *  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.valuesemantics;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+import javax.annotation.Priority;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.springframework.stereotype.Component;
+
+import org.apache.isis.applib.annotation.PriorityPrecedence;
+import org.apache.isis.applib.services.bookmark.IdStringifier;
+import org.apache.isis.applib.services.urlencoding.UrlEncodingService;
+import org.apache.isis.applib.value.semantics.ValueDecomposition;
+import org.apache.isis.applib.value.semantics.ValueSemanticsAbstract;
+import org.apache.isis.applib.value.semantics.ValueSemanticsProvider;
+import org.apache.isis.commons.collections.Can;
+import org.apache.isis.commons.internal.base._Strings;
+import org.apache.isis.commons.internal.resources._Serializables;
+import org.apache.isis.schema.common.v2.ValueType;
+
+import lombok.NonNull;
+
+/**
+ * Used as a fallback if no other {@link ValueSemanticsProvider}
+ * is available to handle the corresponding value type.
+ */
+@Component
+@Named("isis.val.SerializableValueSemantics")
+@Priority(PriorityPrecedence.LAST)
+public class SerializableValueSemantics
+extends ValueSemanticsAbstract<Serializable>
+implements
+    IdStringifier<Serializable> {
+
+    private final UrlEncodingService codec;
+
+    @Inject
+    public SerializableValueSemantics(
+            final @NonNull UrlEncodingService codec) {
+        this.codec = codec;
+    }
+
+    @Override
+    public Class<Serializable> getCorrespondingClass() {
+        return Serializable.class;
+    }
+
+    @Override
+    public ValueType getSchemaValueType() {
+        return ValueType.STRING;
+    }
+
+    // -- COMPOSER
+
+    @Override
+    public ValueDecomposition decompose(final Serializable value) {
+        return decomposeAsString(value, this::enstring, ()->null);
+    }
+
+    @Override
+    public Serializable compose(final ValueDecomposition decomposition) {
+        return composeFromString(decomposition, this::destring, ()->null);
+    }
+
+    // -- ID STRINGIFIER
+
+    @Override
+    public String enstring(final @NonNull Serializable id) {
+        // even though null case is guarded by lombok - keep null check for 
symmetry
+        return id != null
+                ? codec.encode(_Serializables.write(id))
+                : null;
+    }
+
+    @Override
+    public Serializable destring(
+            final @NonNull String stringified,
+            final @NonNull Class<?> targetEntityClass) {
+        return destring(stringified);
+    }
+
+    @Override
+    public Can<Serializable> getExamples() {
+        return Can.of(
+                Integer.MAX_VALUE,
+                "Hallo World",
+                new BigDecimal("3.1415"));
+    }
+
+    // -- HELPER
+
+    private Serializable destring(
+            @NonNull final String stringified) {
+        return destringAs(stringified, Serializable.class);
+    }
+
+    private <T extends Serializable> T destringAs(
+            final @NonNull String stringified,
+            final @NonNull Class<T> requiredClass) {
+        return _Strings.isNotEmpty(stringified)
+                ? _Serializables.read(requiredClass, codec.decode(stringified))
+                : null;
+    }
+
+
+}
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/ShortValueSemantics.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/ShortValueSemantics.java
index bb9d2b0c2d..c5071c822d 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/ShortValueSemantics.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/ShortValueSemantics.java
@@ -21,11 +21,14 @@ package org.apache.isis.core.metamodel.valuesemantics;
 import java.math.BigInteger;
 import java.util.function.UnaryOperator;
 
+import javax.annotation.Priority;
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
+import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.exceptions.recoverable.TextEntryParseException;
+import org.apache.isis.applib.services.bookmark.IdStringifier;
 import org.apache.isis.applib.value.semantics.DefaultsProvider;
 import org.apache.isis.applib.value.semantics.Parser;
 import org.apache.isis.applib.value.semantics.Renderer;
@@ -36,6 +39,7 @@ import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.schema.common.v2.ValueType;
 import org.apache.isis.schema.common.v2.ValueWithTypeDto;
 
+import lombok.NonNull;
 import lombok.val;
 
 /**
@@ -43,12 +47,14 @@ import lombok.val;
  */
 @Component
 @Named("isis.val.ShortValueSemantics")
+@Priority(PriorityPrecedence.LATE)
 public class ShortValueSemantics
 extends ValueSemanticsAbstract<Short>
 implements
     DefaultsProvider<Short>,
     Parser<Short>,
-    Renderer<Short> {
+    Renderer<Short>,
+    IdStringifier<Short> {
 
     @Override
     public Class<Short> getCorrespondingClass() {
@@ -78,6 +84,20 @@ implements
                 decomposition, ValueWithTypeDto::getShort, 
UnaryOperator.identity(), ()->null);
     }
 
+    // -- ID STRINGIFIER
+
+    @Override
+    public String enstring(final @NonNull Short value) {
+        return value.toString();
+    }
+
+    @Override
+    public Short destring(
+            final @NonNull String stringified,
+            final @NonNull Class<?> targetEntityClass) {
+        return Short.parseShort(stringified);
+    }
+
     // -- RENDERER
 
     @Override
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/StringValueSemantics.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/StringValueSemantics.java
index 3f66002a7c..9021cd8787 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/StringValueSemantics.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/StringValueSemantics.java
@@ -18,26 +18,36 @@
  */
 package org.apache.isis.core.metamodel.valuesemantics;
 
+import java.util.Arrays;
+import java.util.List;
 import java.util.function.UnaryOperator;
 
+import javax.annotation.Priority;
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
+import org.apache.isis.applib.annotation.PriorityPrecedence;
+import org.apache.isis.applib.services.bookmark.IdStringifier;
 import org.apache.isis.applib.value.semantics.Parser;
 import org.apache.isis.applib.value.semantics.Renderer;
 import org.apache.isis.applib.value.semantics.ValueDecomposition;
 import org.apache.isis.applib.value.semantics.ValueSemanticsAbstract;
 import org.apache.isis.commons.collections.Can;
+import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.schema.common.v2.ValueType;
 
+import lombok.NonNull;
+
 @Component
 @Named("isis.val.StringValueSemantics")
+@Priority(PriorityPrecedence.LATE)
 public class StringValueSemantics
 extends ValueSemanticsAbstract<String>
 implements
     Parser<String>,
-    Renderer<String> {
+    Renderer<String>,
+    IdStringifier<String> {
 
     @Override
     public Class<String> getCorrespondingClass() {
@@ -61,6 +71,34 @@ implements
         return composeFromString(decomposition, UnaryOperator.identity(), 
()->null);
     }
 
+    // -- ID STRINGIFIER
+
+    static final List<String> NON_SAFE_URL_CHARS =
+            Arrays.asList("/", "\\", "?", ":", "&", "%", "+");
+    static final String REGULAR_PREFIX = "s" + 
IdStringifier.AbstractWithPrefix.SEPARATOR;
+    static final String BASE64_PREFIX = "base64" + 
IdStringifier.AbstractWithPrefix.SEPARATOR;
+
+    @Override
+    public String enstring(final @NonNull String id) {
+        if(NON_SAFE_URL_CHARS.stream().anyMatch(id::contains)) {
+            return BASE64_PREFIX + _Strings.base64UrlEncode(id);
+        }
+        return REGULAR_PREFIX + id;
+    }
+
+    @Override
+    public String destring(
+            final @NonNull String stringified,
+            final @NonNull Class<?> targetEntityClass) {
+        if(stringified.startsWith(REGULAR_PREFIX)) {
+            return stringified.substring(REGULAR_PREFIX.length());
+        }
+        if(stringified.startsWith(BASE64_PREFIX)) {
+            return 
_Strings.base64UrlDecode(stringified.substring(BASE64_PREFIX.length()));
+        }
+        throw new IllegalArgumentException(String.format("Could not parse 
stringified id '%s'", stringified));
+    }
+
     // -- RENDERER
 
     @Override
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/TreeNodeValueSemantics.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/TreeNodeValueSemantics.java
index dcf5dd3463..ca072e8b72 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/TreeNodeValueSemantics.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/TreeNodeValueSemantics.java
@@ -21,11 +21,13 @@ package org.apache.isis.core.metamodel.valuesemantics;
 import java.util.Optional;
 import java.util.stream.Stream;
 
+import javax.annotation.Priority;
 import javax.inject.Inject;
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
+import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.graph.tree.TreeAdapter;
 import org.apache.isis.applib.graph.tree.TreeNode;
 import org.apache.isis.applib.graph.tree.TreeState;
@@ -42,6 +44,7 @@ import org.apache.isis.schema.common.v2.ValueType;
 
 @Component
 @Named("isis.val.TreeNodeValueSemantics")
+@Priority(PriorityPrecedence.LATE)
 public class TreeNodeValueSemantics
 extends ValueSemanticsAbstract<TreeNode<?>>
 implements
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/URLValueSemantics.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/URLValueSemantics.java
index 77c1a75bd5..d5c66429cf 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/URLValueSemantics.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/URLValueSemantics.java
@@ -21,10 +21,12 @@ package org.apache.isis.core.metamodel.valuesemantics;
 import java.net.MalformedURLException;
 import java.net.URL;
 
+import javax.annotation.Priority;
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
+import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.value.semantics.Parser;
 import org.apache.isis.applib.value.semantics.Renderer;
 import org.apache.isis.applib.value.semantics.ValueDecomposition;
@@ -40,6 +42,7 @@ import lombok.val;
 
 @Component
 @Named("isis.val.URLValueSemantics")
+@Priority(PriorityPrecedence.LATE)
 public class URLValueSemantics
 extends ValueSemanticsAbstract<java.net.URL>
 implements
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/UUIDValueSemantics.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/UUIDValueSemantics.java
index f0c1ba3e86..75563c08cb 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/UUIDValueSemantics.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/valuesemantics/UUIDValueSemantics.java
@@ -20,10 +20,13 @@ package org.apache.isis.core.metamodel.valuesemantics;
 
 import java.util.UUID;
 
+import javax.annotation.Priority;
 import javax.inject.Named;
 
 import org.springframework.stereotype.Component;
 
+import org.apache.isis.applib.annotation.PriorityPrecedence;
+import org.apache.isis.applib.services.bookmark.IdStringifier;
 import org.apache.isis.applib.value.semantics.Parser;
 import org.apache.isis.applib.value.semantics.Renderer;
 import org.apache.isis.applib.value.semantics.ValueDecomposition;
@@ -33,15 +36,18 @@ import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.schema.common.v2.ValueType;
 
+import lombok.NonNull;
 import lombok.val;
 
 @Component
 @Named("isis.val.UUIDValueSemantics")
+@Priority(PriorityPrecedence.LATE)
 public class UUIDValueSemantics
 extends ValueSemanticsAbstract<UUID>
 implements
     Parser<UUID>,
-    Renderer<UUID> {
+    Renderer<UUID>,
+    IdStringifier<UUID> {
 
     @Override
     public Class<UUID> getCorrespondingClass() {
@@ -65,6 +71,18 @@ implements
         return composeFromString(decomposition, UUID::fromString, ()->null);
     }
 
+    // -- ID STRINGIFIER
+
+    @Override
+    public String enstring(final @NonNull UUID value) {
+        return value.toString();
+    }
+
+    @Override
+    public UUID destring(final @NonNull String stringified, @NonNull final 
Class<?> targetEntityClass) {
+        return UUID.fromString(stringified);
+    }
+
     // -- RENDERER
 
     @Override
diff --git 
a/api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForBigDecimal_Test.java
 
b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForBigDecimal_Test.java
similarity index 90%
rename from 
api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForBigDecimal_Test.java
rename to 
core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForBigDecimal_Test.java
index 86cc43ff5b..22e6594b6b 100644
--- 
a/api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForBigDecimal_Test.java
+++ 
b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForBigDecimal_Test.java
@@ -18,7 +18,7 @@
  *
  */
 
-package org.apache.isis.applib.services.bookmark;
+package org.apache.isis.core.metamodel.valuesemantics;
 
 import java.math.BigDecimal;
 import java.util.stream.Stream;
@@ -29,8 +29,6 @@ import org.junit.jupiter.params.provider.MethodSource;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
-import 
org.apache.isis.applib.services.bookmark.idstringifiers.IdStringifierForBigDecimal;
-
 import lombok.val;
 
 class IdStringifierForBigDecimal_Test {
@@ -56,9 +54,9 @@ class IdStringifierForBigDecimal_Test {
 
     @ParameterizedTest
     @MethodSource()
-    void roundtrip(BigDecimal bigDecimal) {
+    void roundtrip(final BigDecimal bigDecimal) {
 
-        val stringifier = new IdStringifierForBigDecimal();
+        val stringifier = new BigDecimalValueSemantics();
 
         String stringified = stringifier.enstring(bigDecimal);
         BigDecimal parse = stringifier.destring(stringified, Customer.class);
diff --git 
a/api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForBigInteger_Test.java
 
b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForBigInteger_Test.java
similarity index 87%
rename from 
api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForBigInteger_Test.java
rename to 
core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForBigInteger_Test.java
index d9e5c741d2..20ce00e7e7 100644
--- 
a/api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForBigInteger_Test.java
+++ 
b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForBigInteger_Test.java
@@ -18,7 +18,7 @@
  *
  */
 
-package org.apache.isis.applib.services.bookmark;
+package org.apache.isis.core.metamodel.valuesemantics;
 
 import java.math.BigInteger;
 import java.util.stream.Stream;
@@ -27,9 +27,7 @@ import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.MethodSource;
 
-import static org.assertj.core.api.Assertions.*;
-
-import 
org.apache.isis.applib.services.bookmark.idstringifiers.IdStringifierForBigInteger;
+import static org.assertj.core.api.Assertions.assertThat;
 
 import lombok.val;
 
@@ -53,9 +51,9 @@ class IdStringifierForBigInteger_Test {
 
     @ParameterizedTest
     @MethodSource()
-    void roundtrip(BigInteger bigInteger) {
+    void roundtrip(final BigInteger bigInteger) {
 
-        val stringifier = new IdStringifierForBigInteger();
+        val stringifier = new BigIntegerValueSemantics();
 
         String stringified = stringifier.enstring(bigInteger);
         BigInteger parse = stringifier.destring(stringified, Customer.class);
diff --git 
a/api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForByte_Test.java
 
b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForByte_Test.java
similarity index 88%
rename from 
api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForByte_Test.java
rename to 
core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForByte_Test.java
index aca931e155..f7424b1a43 100644
--- 
a/api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForByte_Test.java
+++ 
b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForByte_Test.java
@@ -18,7 +18,7 @@
  *
  */
 
-package org.apache.isis.applib.services.bookmark;
+package org.apache.isis.core.metamodel.valuesemantics;
 
 import java.util.stream.Stream;
 
@@ -28,8 +28,6 @@ import org.junit.jupiter.params.provider.MethodSource;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
-import 
org.apache.isis.applib.services.bookmark.idstringifiers.IdStringifierForByte;
-
 import lombok.val;
 
 class IdStringifierForByte_Test {
@@ -48,9 +46,9 @@ class IdStringifierForByte_Test {
 
     @ParameterizedTest
     @MethodSource()
-    void roundtrip(Byte value) {
+    void roundtrip(final Byte value) {
 
-        val stringifier = new IdStringifierForByte();
+        val stringifier = new ByteValueSemantics();
 
         String stringified = stringifier.enstring(value);
         Byte parse = stringifier.destring(stringified, Customer.class);
diff --git 
a/api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForByte_primitive_Test.java
 
b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForByte_primitive_Test.java
similarity index 88%
rename from 
api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForByte_primitive_Test.java
rename to 
core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForByte_primitive_Test.java
index 73e836c041..e3430968bd 100644
--- 
a/api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForByte_primitive_Test.java
+++ 
b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForByte_primitive_Test.java
@@ -18,7 +18,7 @@
  *
  */
 
-package org.apache.isis.applib.services.bookmark;
+package org.apache.isis.core.metamodel.valuesemantics;
 
 import java.util.stream.Stream;
 
@@ -28,8 +28,6 @@ import org.junit.jupiter.params.provider.MethodSource;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
-import 
org.apache.isis.applib.services.bookmark.idstringifiers.IdStringifierForByte;
-
 import lombok.val;
 
 class IdStringifierForByte_primitive_Test {
@@ -49,9 +47,9 @@ class IdStringifierForByte_primitive_Test {
 
     @ParameterizedTest
     @MethodSource()
-    void roundtrip(byte value) {
+    void roundtrip(final byte value) {
 
-        val stringifier = new IdStringifierForByte();
+        val stringifier = new ByteValueSemantics();
 
         String stringified = stringifier.enstring(value);
         Byte parse = stringifier.destring(stringified, Customer.class);
diff --git 
a/api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForCharacter_Test.java
 
b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForCharacter_Test.java
similarity index 90%
rename from 
api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForCharacter_Test.java
rename to 
core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForCharacter_Test.java
index 2575ad7e65..ea42a09394 100644
--- 
a/api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForCharacter_Test.java
+++ 
b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForCharacter_Test.java
@@ -18,7 +18,7 @@
  *
  */
 
-package org.apache.isis.applib.services.bookmark;
+package org.apache.isis.core.metamodel.valuesemantics;
 
 import java.util.stream.Stream;
 
@@ -27,8 +27,6 @@ import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.MethodSource;
 
-import 
org.apache.isis.applib.services.bookmark.idstringifiers.IdStringifierForCharacter;
-
 import lombok.val;
 
 class IdStringifierForCharacter_Test {
@@ -63,9 +61,9 @@ class IdStringifierForCharacter_Test {
 
     @ParameterizedTest
     @MethodSource()
-    void roundtrip(char value) {
+    void roundtrip(final char value) {
 
-        val stringifier = new IdStringifierForCharacter();
+        val stringifier = new CharacterValueSemantics();
 
         val stringified = stringifier.enstring(value);
         val parse = stringifier.destring(stringified, Customer.class);
diff --git 
a/api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForInteger_Test.java
 
b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForInteger_Test.java
similarity index 87%
rename from 
api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForInteger_Test.java
rename to 
core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForInteger_Test.java
index 14cc713663..6329c3cf4f 100644
--- 
a/api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForInteger_Test.java
+++ 
b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForInteger_Test.java
@@ -18,7 +18,7 @@
  *
  */
 
-package org.apache.isis.applib.services.bookmark;
+package org.apache.isis.core.metamodel.valuesemantics;
 
 import java.util.stream.Stream;
 
@@ -28,8 +28,6 @@ import org.junit.jupiter.params.provider.MethodSource;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
-import 
org.apache.isis.applib.services.bookmark.idstringifiers.IdStringifierForInteger;
-
 import lombok.val;
 
 class IdStringifierForInteger_Test {
@@ -49,9 +47,9 @@ class IdStringifierForInteger_Test {
 
     @ParameterizedTest
     @MethodSource()
-    void roundtrip(Integer value) {
+    void roundtrip(final Integer value) {
 
-        val stringifier = new IdStringifierForInteger();
+        val stringifier = new IntValueSemantics();
 
         String stringified = stringifier.enstring(value);
         Integer parse = stringifier.destring(stringified, Customer.class);
diff --git 
a/api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForInteger_primitive_Test.java
 
b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForInteger_primitive_Test.java
similarity index 88%
rename from 
api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForInteger_primitive_Test.java
rename to 
core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForInteger_primitive_Test.java
index 848ee60048..1eb6aa1696 100644
--- 
a/api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForInteger_primitive_Test.java
+++ 
b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForInteger_primitive_Test.java
@@ -18,7 +18,7 @@
  *
  */
 
-package org.apache.isis.applib.services.bookmark;
+package org.apache.isis.core.metamodel.valuesemantics;
 
 import java.util.stream.Stream;
 
@@ -28,8 +28,6 @@ import org.junit.jupiter.params.provider.MethodSource;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
-import 
org.apache.isis.applib.services.bookmark.idstringifiers.IdStringifierForInteger;
-
 import lombok.val;
 
 class IdStringifierForInteger_primitive_Test {
@@ -48,9 +46,9 @@ class IdStringifierForInteger_primitive_Test {
 
     @ParameterizedTest
     @MethodSource()
-    void roundtrip(int value) {
+    void roundtrip(final int value) {
 
-        val stringifier = new IdStringifierForInteger();
+        val stringifier = new IntValueSemantics();
 
         String stringified = stringifier.enstring(value);
         Integer parse = stringifier.destring(stringified, Customer.class);
diff --git 
a/api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForLong_Test.java
 
b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForLong_Test.java
similarity index 88%
rename from 
api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForLong_Test.java
rename to 
core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForLong_Test.java
index ba65593405..628f854b48 100644
--- 
a/api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForLong_Test.java
+++ 
b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForLong_Test.java
@@ -18,7 +18,7 @@
  *
  */
 
-package org.apache.isis.applib.services.bookmark;
+package org.apache.isis.core.metamodel.valuesemantics;
 
 import java.util.stream.Stream;
 
@@ -28,8 +28,6 @@ import org.junit.jupiter.params.provider.MethodSource;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
-import 
org.apache.isis.applib.services.bookmark.idstringifiers.IdStringifierForLong;
-
 import lombok.val;
 
 class IdStringifierForLong_Test {
@@ -48,9 +46,9 @@ class IdStringifierForLong_Test {
 
     @ParameterizedTest
     @MethodSource()
-    void roundtrip(Long value) {
+    void roundtrip(final Long value) {
 
-        val stringifier = new IdStringifierForLong();
+        val stringifier = new LongValueSemantics();
 
         String stringified = stringifier.enstring(value);
         Long parse = stringifier.destring(stringified, Customer.class);
diff --git 
a/api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForLong_primitive_Test.java
 
b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForLong_primitive_Test.java
similarity index 88%
rename from 
api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForLong_primitive_Test.java
rename to 
core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForLong_primitive_Test.java
index f54f72cc8d..6d64e88e31 100644
--- 
a/api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForLong_primitive_Test.java
+++ 
b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForLong_primitive_Test.java
@@ -18,7 +18,7 @@
  *
  */
 
-package org.apache.isis.applib.services.bookmark;
+package org.apache.isis.core.metamodel.valuesemantics;
 
 import java.util.stream.Stream;
 
@@ -28,8 +28,6 @@ import org.junit.jupiter.params.provider.MethodSource;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
-import 
org.apache.isis.applib.services.bookmark.idstringifiers.IdStringifierForLong;
-
 import lombok.val;
 
 class IdStringifierForLong_primitive_Test {
@@ -49,9 +47,9 @@ class IdStringifierForLong_primitive_Test {
 
     @ParameterizedTest
     @MethodSource()
-    void roundtrip(long value) {
+    void roundtrip(final long value) {
 
-        val stringifier = new IdStringifierForLong();
+        val stringifier = new LongValueSemantics();
 
         String stringified = stringifier.enstring(value);
         Long parse = stringifier.destring(stringified, Customer.class);
diff --git 
a/api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForSerializable_Test.java
 
b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForSerializable_Test.java
similarity index 91%
rename from 
api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForSerializable_Test.java
rename to 
core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForSerializable_Test.java
index a802b6fc5f..646fe680ff 100644
--- 
a/api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForSerializable_Test.java
+++ 
b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForSerializable_Test.java
@@ -18,7 +18,7 @@
  *
  */
 
-package org.apache.isis.applib.services.bookmark;
+package org.apache.isis.core.metamodel.valuesemantics;
 
 import java.io.Serializable;
 import java.util.stream.Stream;
@@ -29,7 +29,6 @@ import org.junit.jupiter.params.provider.MethodSource;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
-import 
org.apache.isis.applib.services.bookmark.idstringifiers.IdStringifierForSerializable;
 import org.apache.isis.applib.services.urlencoding.UrlEncodingService;
 
 import lombok.Value;
@@ -69,7 +68,7 @@ class IdStringifierForSerializable_Test {
     @MethodSource()
     void roundtrip(final Serializable value) {
 
-        val stringifier = new IdStringifierForSerializable(codec);
+        val stringifier = new SerializableValueSemantics(codec);
 
         String stringified = stringifier.enstring(value);
         Serializable parse = stringifier.destring(stringified, Customer.class);
diff --git 
a/api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForShort_Test.java
 
b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForShort_Test.java
similarity index 88%
rename from 
api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForShort_Test.java
rename to 
core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForShort_Test.java
index 1f7ca5b4f9..27d8907785 100644
--- 
a/api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForShort_Test.java
+++ 
b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForShort_Test.java
@@ -18,7 +18,7 @@
  *
  */
 
-package org.apache.isis.applib.services.bookmark;
+package org.apache.isis.core.metamodel.valuesemantics;
 
 import java.util.stream.Stream;
 
@@ -28,8 +28,6 @@ import org.junit.jupiter.params.provider.MethodSource;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
-import 
org.apache.isis.applib.services.bookmark.idstringifiers.IdStringifierForShort;
-
 import lombok.val;
 
 class IdStringifierForShort_Test {
@@ -48,9 +46,9 @@ class IdStringifierForShort_Test {
 
     @ParameterizedTest
     @MethodSource()
-    void roundtrip(Short value) {
+    void roundtrip(final Short value) {
 
-        val stringifier = new IdStringifierForShort();
+        val stringifier = new ShortValueSemantics();
 
         String stringified = stringifier.enstring(value);
         Short parse = stringifier.destring(stringified, Customer.class);
diff --git 
a/api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForShort_primitive_Test.java
 
b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForShort_primitive_Test.java
similarity index 88%
rename from 
api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForShort_primitive_Test.java
rename to 
core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForShort_primitive_Test.java
index a36186e2c6..9ad428493c 100644
--- 
a/api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForShort_primitive_Test.java
+++ 
b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForShort_primitive_Test.java
@@ -18,7 +18,7 @@
  *
  */
 
-package org.apache.isis.applib.services.bookmark;
+package org.apache.isis.core.metamodel.valuesemantics;
 
 import java.util.stream.Stream;
 
@@ -28,8 +28,6 @@ import org.junit.jupiter.params.provider.MethodSource;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
-import 
org.apache.isis.applib.services.bookmark.idstringifiers.IdStringifierForShort;
-
 import lombok.val;
 
 class IdStringifierForShort_primitive_Test {
@@ -48,9 +46,9 @@ class IdStringifierForShort_primitive_Test {
 
     @ParameterizedTest
     @MethodSource()
-    void roundtrip(short value) {
+    void roundtrip(final short value) {
 
-        val stringifier = new IdStringifierForShort();
+        val stringifier = new ShortValueSemantics();
 
         String stringified = stringifier.enstring(value);
         Short parse = stringifier.destring(stringified, Customer.class);
diff --git 
a/api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForString_Test.java
 
b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForString_Test.java
similarity index 91%
rename from 
api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForString_Test.java
rename to 
core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForString_Test.java
index 0341e5a79d..be2a222542 100644
--- 
a/api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForString_Test.java
+++ 
b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForString_Test.java
@@ -18,7 +18,7 @@
  *
  */
 
-package org.apache.isis.applib.services.bookmark;
+package org.apache.isis.core.metamodel.valuesemantics;
 
 import java.util.stream.Stream;
 
@@ -27,8 +27,6 @@ import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.MethodSource;
 
-import 
org.apache.isis.applib.services.bookmark.idstringifiers.IdStringifierForString;
-
 import lombok.val;
 
 class IdStringifierForString_Test {
@@ -53,9 +51,9 @@ class IdStringifierForString_Test {
 
     @ParameterizedTest
     @MethodSource()
-    void roundtrip(String value) {
+    void roundtrip(final String value) {
 
-        val stringifier = new IdStringifierForString();
+        val stringifier = new StringValueSemantics();
 
         val stringified = stringifier.enstring(value);
         val parse = stringifier.destring(stringified, Customer.class);
diff --git 
a/api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForUuid_Test.java
 
b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForUuid_Test.java
similarity index 88%
rename from 
api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForUuid_Test.java
rename to 
core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForUuid_Test.java
index 610264f90f..72b57bfa35 100644
--- 
a/api/applib/src/test/java/org/apache/isis/applib/services/bookmark/IdStringifierForUuid_Test.java
+++ 
b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/valuesemantics/IdStringifierForUuid_Test.java
@@ -18,7 +18,7 @@
  *
  */
 
-package org.apache.isis.applib.services.bookmark;
+package org.apache.isis.core.metamodel.valuesemantics;
 
 import java.util.UUID;
 import java.util.stream.Stream;
@@ -29,8 +29,6 @@ import org.junit.jupiter.params.provider.MethodSource;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
-import 
org.apache.isis.applib.services.bookmark.idstringifiers.IdStringifierForUuid;
-
 import lombok.val;
 
 class IdStringifierForUuid_Test {
@@ -47,9 +45,9 @@ class IdStringifierForUuid_Test {
 
     @ParameterizedTest
     @MethodSource()
-    void roundtrip(UUID value) {
+    void roundtrip(final UUID value) {
 
-        val stringifier = new IdStringifierForUuid();
+        val stringifier = new UUIDValueSemantics();
 
         String stringified = stringifier.enstring(value);
         UUID parse = stringifier.destring(stringified, Customer.class);
diff --git 
a/core/runtime/src/main/java/org/apache/isis/core/runtime/idstringifier/IdStringifierLookupService.java
 
b/core/runtime/src/main/java/org/apache/isis/core/runtime/idstringifier/IdStringifierLookupService.java
index dcde5b425c..984aacdeb7 100644
--- 
a/core/runtime/src/main/java/org/apache/isis/core/runtime/idstringifier/IdStringifierLookupService.java
+++ 
b/core/runtime/src/main/java/org/apache/isis/core/runtime/idstringifier/IdStringifierLookupService.java
@@ -20,6 +20,7 @@
 
 package org.apache.isis.core.runtime.idstringifier;
 
+import java.io.Serializable;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
@@ -34,7 +35,6 @@ import org.springframework.stereotype.Service;
 
 import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.services.bookmark.IdStringifier;
-import 
org.apache.isis.applib.services.bookmark.idstringifiers.IdStringifierForSerializable;
 import org.apache.isis.commons.collections.Can;
 import org.apache.isis.commons.internal.base._Casts;
 import org.apache.isis.core.runtime.IsisModuleCoreRuntime;
@@ -63,12 +63,13 @@ public class IdStringifierLookupService {
     @Inject
     public IdStringifierLookupService(
             final List<IdStringifier<?>> idStringifiers,
-            final Optional<IdStringifierForSerializable> 
idStringifierForSerializableIfAny) {
+            final Optional<IdStringifier<Serializable>> 
idStringifierForSerializableIfAny) {
         // IdStringifierForSerializable is enforced to go last, so any custom 
IdStringifier(s)
         // that do not explicitly specify an @Order/@Precedence go earlier
         idStringifierForSerializableIfAny
         .ifPresent(idStringifierForSerializable->{
-            
idStringifiers.removeIf(idStringifier->IdStringifierForSerializable.class.equals(idStringifier.getClass()));
+            
idStringifiers.removeIf(idStringifier->idStringifierForSerializable.getClass()
+                    .equals(idStringifier.getClass()));
             idStringifiers.add(idStringifierForSerializable); // put last
         });
         this.idStringifiers = Can.ofCollection(idStringifiers);
diff --git 
a/extensions/core/commandlog/persistence-jpa/src/main/java/org/apache/isis/extensions/commandlog/jpa/IsisModuleExtCommandLogPersistenceJpa.java
 
b/extensions/core/commandlog/persistence-jpa/src/main/java/org/apache/isis/extensions/commandlog/jpa/IsisModuleExtCommandLogPersistenceJpa.java
index 2f5ba7e2eb..7a0d197a7a 100644
--- 
a/extensions/core/commandlog/persistence-jpa/src/main/java/org/apache/isis/extensions/commandlog/jpa/IsisModuleExtCommandLogPersistenceJpa.java
+++ 
b/extensions/core/commandlog/persistence-jpa/src/main/java/org/apache/isis/extensions/commandlog/jpa/IsisModuleExtCommandLogPersistenceJpa.java
@@ -44,7 +44,7 @@ import 
org.apache.isis.testing.fixtures.applib.teardown.jpa.TeardownFixtureJpaAb
 
         // @Service's
         CommandLogEntryRepository.class,
-        CommandLogEntryPK.Stringifier.class,
+        CommandLogEntryPK.Semantics.class,
 
         // entities
         CommandLogEntry.class
diff --git 
a/extensions/core/commandlog/persistence-jpa/src/main/java/org/apache/isis/extensions/commandlog/jpa/dom/CommandLogEntryPK.java
 
b/extensions/core/commandlog/persistence-jpa/src/main/java/org/apache/isis/extensions/commandlog/jpa/dom/CommandLogEntryPK.java
index d3d2667e3f..073df2a148 100644
--- 
a/extensions/core/commandlog/persistence-jpa/src/main/java/org/apache/isis/extensions/commandlog/jpa/dom/CommandLogEntryPK.java
+++ 
b/extensions/core/commandlog/persistence-jpa/src/main/java/org/apache/isis/extensions/commandlog/jpa/dom/CommandLogEntryPK.java
@@ -31,8 +31,11 @@ import org.springframework.stereotype.Component;
 
 import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.services.bookmark.IdStringifier;
+import org.apache.isis.applib.value.semantics.ValueDecomposition;
+import org.apache.isis.applib.value.semantics.ValueSemanticsAbstract;
 import org.apache.isis.extensions.commandlog.applib.dom.CommandLogEntry;
 import 
org.apache.isis.persistence.jpa.integration.typeconverters.java.util.JavaUtilUuidConverter;
+import org.apache.isis.schema.common.v2.ValueType;
 
 import lombok.AccessLevel;
 import lombok.AllArgsConstructor;
@@ -50,7 +53,10 @@ public class CommandLogEntryPK implements Serializable {
     private static final long serialVersionUID = 1L;
 
     @Convert(converter = JavaUtilUuidConverter.class)
-    @Column(name = CommandLogEntry.InteractionId.NAME, nullable = 
CommandLogEntry.InteractionId.NULLABLE, length = 
CommandLogEntry.InteractionId.MAX_LENGTH)
+    @Column(
+            name = CommandLogEntry.InteractionId.NAME,
+            nullable = CommandLogEntry.InteractionId.NULLABLE,
+            length = CommandLogEntry.InteractionId.MAX_LENGTH)
     @Getter(AccessLevel.PACKAGE)
     private UUID interactionId;
 
@@ -59,23 +65,55 @@ public class CommandLogEntryPK implements Serializable {
         return interactionId != null ? interactionId.toString() : null;
     }
 
-
     @Component
     @Priority(PriorityPrecedence.MIDPOINT)
-    public static class Stringifier extends 
IdStringifier.Abstract<CommandLogEntryPK> {
+    public static class Semantics
+    extends ValueSemanticsAbstract<CommandLogEntryPK>
+    implements IdStringifier<CommandLogEntryPK> {
+
+        @Override
+        public Class<CommandLogEntryPK> getCorrespondingClass() {
+            return CommandLogEntryPK.class;
+        }
+
+        @Override
+        public ValueType getSchemaValueType() {
+            return ValueType.STRING;
+        }
+
+        // -- COMPOSER
 
-        public Stringifier() {
-            super(CommandLogEntryPK.class);
+        @Override
+        public ValueDecomposition decompose(final CommandLogEntryPK value) {
+            return decomposeAsString(value, this::enstring, ()->null);
         }
 
+        @Override
+        public CommandLogEntryPK compose(final ValueDecomposition 
decomposition) {
+            return composeFromString(decomposition, this::destring, ()->null);
+        }
+
+        // -- ID STRINGIFIER
+
         @Override
         public String enstring(final CommandLogEntryPK value) {
             return value.getInteractionId().toString();
         }
 
         @Override
-        public CommandLogEntryPK destring(@NonNull final String stringified, 
@NonNull final Class<?> targetEntityClass) {
+        public CommandLogEntryPK destring(
+                @NonNull final String stringified,
+                @NonNull final Class<?> targetEntityClass) {
+            return destring(stringified);
+        }
+
+        private CommandLogEntryPK destring(
+                @NonNull final String stringified) {
             return new CommandLogEntryPK(UUID.fromString(stringified));
         }
+
+
     }
+
+
 }
diff --git 
a/extensions/core/commandlog/persistence-jpa/src/test/java/org/apache/isis/extensions/commandlog/jpa/dom/CommandLogEntryPK_Stringifier_Test.java
 
b/extensions/core/commandlog/persistence-jpa/src/test/java/org/apache/isis/extensions/commandlog/jpa/dom/CommandLogEntryPK_Stringifier_Test.java
index 972e1d3d8a..31a2fc76f3 100644
--- 
a/extensions/core/commandlog/persistence-jpa/src/test/java/org/apache/isis/extensions/commandlog/jpa/dom/CommandLogEntryPK_Stringifier_Test.java
+++ 
b/extensions/core/commandlog/persistence-jpa/src/test/java/org/apache/isis/extensions/commandlog/jpa/dom/CommandLogEntryPK_Stringifier_Test.java
@@ -45,10 +45,10 @@ class CommandLogEntryPK_Stringifier_Test {
 
     @ParameterizedTest
     @MethodSource()
-    void roundtrip(UUID uuid) {
+    void roundtrip(final UUID uuid) {
         CommandLogEntryPK value = new CommandLogEntryPK(uuid);
 
-        val stringifier = new CommandLogEntryPK.Stringifier();
+        val stringifier = new CommandLogEntryPK.Semantics();
 
         String stringified = stringifier.enstring(value);
         val parse = stringifier.destring(stringified, Customer.class);
diff --git 
a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/IdStringifierForCharId.java
 
b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/IdStringifierForCharId.java
index 5a1b8c1fe8..00797bb422 100644
--- 
a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/IdStringifierForCharId.java
+++ 
b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/IdStringifierForCharId.java
@@ -26,7 +26,6 @@ import org.springframework.stereotype.Component;
 
 import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.services.bookmark.IdStringifier;
-import 
org.apache.isis.applib.services.bookmark.idstringifiers.IdStringifierForCharacter;
 
 import lombok.Builder;
 import lombok.NonNull;
@@ -36,7 +35,7 @@ import lombok.val;
 @Priority(PriorityPrecedence.LATE)
 public class IdStringifierForCharId extends IdStringifier.Abstract<CharId> {
 
-    @Inject IdStringifierForCharacter idStringifierForCharacter;
+    @Inject IdStringifier<Character> idStringifierForCharacter;
 
     public IdStringifierForCharId() {
         super(CharId.class);
@@ -46,7 +45,7 @@ public class IdStringifierForCharId extends 
IdStringifier.Abstract<CharId> {
      * for testing only
      */
     @Builder
-    IdStringifierForCharId(final IdStringifierForCharacter 
idStringifierForCharacter) {
+    IdStringifierForCharId(final IdStringifier<Character> 
idStringifierForCharacter) {
         this();
         this.idStringifierForCharacter = idStringifierForCharacter;
     }
diff --git 
a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/IdStringifierForCharIdentity.java
 
b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/IdStringifierForCharIdentity.java
index 095830df77..5e27490c2b 100644
--- 
a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/IdStringifierForCharIdentity.java
+++ 
b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/IdStringifierForCharIdentity.java
@@ -26,7 +26,6 @@ import org.springframework.stereotype.Component;
 
 import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.services.bookmark.IdStringifier;
-import 
org.apache.isis.applib.services.bookmark.idstringifiers.IdStringifierForCharacter;
 
 import lombok.Builder;
 import lombok.NonNull;
@@ -36,7 +35,7 @@ import lombok.val;
 @Priority(PriorityPrecedence.LATE)
 public class IdStringifierForCharIdentity extends 
IdStringifier.Abstract<CharIdentity> {
 
-    @Inject IdStringifierForCharacter idStringifierForCharacter;
+    @Inject IdStringifier<Character> idStringifierForCharacter;
 
     public IdStringifierForCharIdentity() {
         super(CharIdentity.class);
@@ -46,7 +45,7 @@ public class IdStringifierForCharIdentity extends 
IdStringifier.Abstract<CharIde
      * for testing only
      */
     @Builder
-    IdStringifierForCharIdentity(final IdStringifierForCharacter 
idStringifierForCharacter) {
+    IdStringifierForCharIdentity(final IdStringifier<Character> 
idStringifierForCharacter) {
         this();
         this.idStringifierForCharacter = idStringifierForCharacter;
     }
diff --git 
a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/IdStringifierForStringId.java
 
b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/IdStringifierForStringId.java
index 83046b1b45..ffd4e4e94e 100644
--- 
a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/IdStringifierForStringId.java
+++ 
b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/IdStringifierForStringId.java
@@ -26,7 +26,6 @@ import org.springframework.stereotype.Component;
 
 import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.services.bookmark.IdStringifier;
-import 
org.apache.isis.applib.services.bookmark.idstringifiers.IdStringifierForString;
 
 import lombok.Builder;
 import lombok.NonNull;
@@ -36,7 +35,7 @@ import lombok.val;
 @Priority(PriorityPrecedence.LATE)
 public class IdStringifierForStringId extends 
IdStringifier.Abstract<StringIdentity> {
 
-    @Inject IdStringifierForString idStringifierForString;
+    @Inject IdStringifier<String> idStringifierForString;
 
     public IdStringifierForStringId() {
         super(StringIdentity.class);
@@ -46,7 +45,7 @@ public class IdStringifierForStringId extends 
IdStringifier.Abstract<StringIdent
      * for testing only
      */
     @Builder
-    IdStringifierForStringId(final IdStringifierForString 
idStringifierForString) {
+    IdStringifierForStringId(final IdStringifier<String> 
idStringifierForString) {
         this();
         this.idStringifierForString = idStringifierForString;
     }
diff --git 
a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/IdStringifierForStringIdentity.java
 
b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/IdStringifierForStringIdentity.java
index e5a759d856..0f5c604840 100644
--- 
a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/IdStringifierForStringIdentity.java
+++ 
b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/metamodel/facets/entity/IdStringifierForStringIdentity.java
@@ -26,7 +26,6 @@ import org.springframework.stereotype.Component;
 
 import org.apache.isis.applib.annotation.PriorityPrecedence;
 import org.apache.isis.applib.services.bookmark.IdStringifier;
-import 
org.apache.isis.applib.services.bookmark.idstringifiers.IdStringifierForString;
 
 import lombok.Builder;
 import lombok.NonNull;
@@ -36,7 +35,7 @@ import lombok.val;
 @Priority(PriorityPrecedence.LATE)
 public class IdStringifierForStringIdentity extends 
IdStringifier.Abstract<StringIdentity> {
 
-    @Inject IdStringifierForString idStringifierForString;
+    @Inject IdStringifier<String> idStringifierForString;
 
     public IdStringifierForStringIdentity() {
         super(StringIdentity.class);
@@ -46,7 +45,7 @@ public class IdStringifierForStringIdentity extends 
IdStringifier.Abstract<Strin
      * for testing only
      */
     @Builder
-    IdStringifierForStringIdentity(final IdStringifierForString 
idStringifierForString) {
+    IdStringifierForStringIdentity(final IdStringifier<String> 
idStringifierForString) {
         this();
         this.idStringifierForString = idStringifierForString;
     }
diff --git 
a/persistence/jdo/datanucleus/src/test/java/org/apache/isis/persistence/jdo/datanucleus/oid/IdStringifierForCharIdentity_Test.java
 
b/persistence/jdo/datanucleus/src/test/java/org/apache/isis/persistence/jdo/datanucleus/oid/IdStringifierForCharIdentity_Test.java
index 89ad2f100d..0e7ec6b3e1 100644
--- 
a/persistence/jdo/datanucleus/src/test/java/org/apache/isis/persistence/jdo/datanucleus/oid/IdStringifierForCharIdentity_Test.java
+++ 
b/persistence/jdo/datanucleus/src/test/java/org/apache/isis/persistence/jdo/datanucleus/oid/IdStringifierForCharIdentity_Test.java
@@ -28,9 +28,9 @@ import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.MethodSource;
 
-import static org.assertj.core.api.Assertions.*;
+import static org.assertj.core.api.Assertions.assertThat;
 
-import 
org.apache.isis.applib.services.bookmark.idstringifiers.IdStringifierForCharacter;
+import org.apache.isis.core.metamodel.valuesemantics.CharacterValueSemantics;
 import 
org.apache.isis.persistence.jdo.datanucleus.metamodel.facets.entity.IdStringifierForCharIdentity;
 
 import lombok.val;
@@ -67,11 +67,13 @@ class IdStringifierForCharIdentity_Test {
 
     @ParameterizedTest
     @MethodSource()
-    void roundtrip(char c) {
+    void roundtrip(final char c) {
 
         val entityType = Customer.class;
 
-        val stringifier = 
IdStringifierForCharIdentity.builder().idStringifierForCharacter(new 
IdStringifierForCharacter()).build();
+        val stringifier = IdStringifierForCharIdentity.builder()
+                .idStringifierForCharacter(new CharacterValueSemantics())
+                .build();
 
         val value = new CharIdentity(entityType, c);
         val stringified = stringifier.enstring(value);
diff --git 
a/persistence/jdo/datanucleus/src/test/java/org/apache/isis/persistence/jdo/datanucleus/oid/IdStringifierForObjectIdentity_Test.java
 
b/persistence/jdo/datanucleus/src/test/java/org/apache/isis/persistence/jdo/datanucleus/oid/IdStringifierForObjectIdentity_Test.java
index 96b133a311..ad09b47905 100644
--- 
a/persistence/jdo/datanucleus/src/test/java/org/apache/isis/persistence/jdo/datanucleus/oid/IdStringifierForObjectIdentity_Test.java
+++ 
b/persistence/jdo/datanucleus/src/test/java/org/apache/isis/persistence/jdo/datanucleus/oid/IdStringifierForObjectIdentity_Test.java
@@ -29,7 +29,6 @@ import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.MethodSource;
 
-import 
org.apache.isis.applib.services.bookmark.idstringifiers.IdStringifierForUuid;
 import 
org.apache.isis.persistence.jdo.datanucleus.metamodel.facets.entity.IdStringifierForObjectIdentity;
 
 import lombok.val;
@@ -50,7 +49,7 @@ class IdStringifierForObjectIdentity_Test {
 
     @ParameterizedTest
     @MethodSource()
-    void roundtrip(int value) {
+    void roundtrip(final int value) {
 
         val entityType = Customer.class;
 
diff --git 
a/persistence/jdo/datanucleus/src/test/java/org/apache/isis/persistence/jdo/datanucleus/oid/IdStringifierForStringIdentity_Test.java
 
b/persistence/jdo/datanucleus/src/test/java/org/apache/isis/persistence/jdo/datanucleus/oid/IdStringifierForStringIdentity_Test.java
index d5f0863521..bea155efbb 100644
--- 
a/persistence/jdo/datanucleus/src/test/java/org/apache/isis/persistence/jdo/datanucleus/oid/IdStringifierForStringIdentity_Test.java
+++ 
b/persistence/jdo/datanucleus/src/test/java/org/apache/isis/persistence/jdo/datanucleus/oid/IdStringifierForStringIdentity_Test.java
@@ -29,7 +29,7 @@ import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.MethodSource;
 
-import 
org.apache.isis.applib.services.bookmark.idstringifiers.IdStringifierForString;
+import org.apache.isis.core.metamodel.valuesemantics.StringValueSemantics;
 import 
org.apache.isis.persistence.jdo.datanucleus.metamodel.facets.entity.IdStringifierForStringIdentity;
 
 import lombok.val;
@@ -55,11 +55,12 @@ class IdStringifierForStringIdentity_Test {
 
     @ParameterizedTest
     @MethodSource()
-    void roundtrip(String value) {
+    void roundtrip(final String value) {
 
         val entityType = Customer.class;
 
-        val stringifier = 
IdStringifierForStringIdentity.builder().idStringifierForString(new 
IdStringifierForString()).build();
+        val stringifier = IdStringifierForStringIdentity.builder()
+                .idStringifierForString(new StringValueSemantics()).build();
 
         val stringified = stringifier.enstring(new StringIdentity(entityType, 
value));
         val parse = stringifier.destring(stringified, entityType);

Reply via email to