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

danhaywood pushed a commit to branch CAUSEWAY-3676
in repository https://gitbox.apache.org/repos/asf/causeway.git

commit 6359a8cb116b30769c826a9db0841afed885fa4f
Author: danhaywood <[email protected]>
AuthorDate: Mon Mar 11 08:29:27 2024 +0000

    CAUSEWAY-3676: adds asciiId to @Property, @Collection, @Action, @Parameter 
...
    
    and uses it within graphql viewer
---
 .../apache/causeway/applib/annotation/Action.java  | 12 ++++++
 .../causeway/applib/annotation/Collection.java     | 13 ++++++
 .../causeway/applib/annotation/Parameter.java      | 13 ++++++
 .../causeway/applib/annotation/Property.java       | 12 ++++++
 core/metamodel/src/main/java/module-info.java      |  1 +
 .../action/ActionAnnotationFacetFactory.java       | 12 ++++++
 .../ascii/AsciiFacetForActionAnnotation.java       | 46 +++++++++++++++++++++
 .../metamodel/facets/all/ascii/AsciiFacet.java     | 29 +++++++++++++
 .../facets/all/ascii/AsciiFacetAbstract.java       | 48 ++++++++++++++++++++++
 .../CollectionAnnotationFacetFactory.java          | 14 +++++++
 .../ascii/AsciiFacetForCollectionAnnotation.java   | 48 ++++++++++++++++++++++
 .../ascii/AsciiFacetForParameterAnnotation.java    | 47 +++++++++++++++++++++
 .../parameter/ParameterAnnotationFacetFactory.java | 13 ++++++
 .../ascii/AsciiFacetForPropertyAnnotation.java     | 48 ++++++++++++++++++++++
 .../property/PropertyAnnotationFacetFactory.java   | 15 +++++++
 .../specimpl/ObjectActionParameterAbstract.java    |  1 +
 .../viewer/graphql/model/domain/TypeNames.java     | 35 ++++++++--------
 .../domain/common/query/CommonDomainObject.java    |  2 +-
 ...monActionUtils.java => ObjectFeatureUtils.java} | 14 +++++--
 .../domain/common/query/meta/CommonMetaSaveAs.java |  4 +-
 .../rich/mutation/RichMutationForAction.java       | 20 ++++-----
 .../rich/mutation/RichMutationForProperty.java     | 12 +++---
 .../model/domain/rich/query/RichAction.java        | 20 ++++-----
 .../domain/rich/query/RichActionInvokeArgsArg.java | 11 ++---
 .../domain/rich/query/RichActionParamsParam.java   |  3 +-
 .../query/RichActionParamsParamAutoComplete.java   |  5 ++-
 .../rich/query/RichActionParamsParamChoices.java   |  5 ++-
 .../rich/query/RichActionParamsParamDefault.java   |  3 +-
 .../rich/query/RichActionParamsParamDisabled.java  |  3 +-
 .../rich/query/RichActionParamsParamHidden.java    |  5 ++-
 .../rich/query/RichActionParamsParamValidate.java  |  3 +-
 .../domain/rich/query/RichActionValidity.java      |  3 +-
 .../model/domain/rich/query/RichCollection.java    |  3 +-
 .../model/domain/rich/query/RichProperty.java      |  9 ++--
 .../rich/query/RichPropertyGetBlobBytes.java       |  3 +-
 .../rich/query/RichPropertyGetClobChars.java       |  3 +-
 .../model/domain/rich/query/RichPropertySet.java   | 19 +++++----
 .../domain/rich/query/RichPropertyValidate.java    |  9 ++--
 .../simple/mutation/SimpleMutationForAction.java   | 22 +++++-----
 .../simple/mutation/SimpleMutationForProperty.java | 12 +++---
 .../model/domain/simple/query/SimpleAction.java    | 24 +++++------
 .../domain/simple/query/SimpleCollection.java      |  3 +-
 .../model/domain/simple/query/SimpleProperty.java  |  3 +-
 .../simple/query/SimplePropertyLobBytes.java       |  3 +-
 .../simple/query/SimplePropertyLobChars.java       |  3 +-
 45 files changed, 517 insertions(+), 119 deletions(-)

diff --git 
a/api/applib/src/main/java/org/apache/causeway/applib/annotation/Action.java 
b/api/applib/src/main/java/org/apache/causeway/applib/annotation/Action.java
index a8b85b61e5..9795ecfaf4 100644
--- a/api/applib/src/main/java/org/apache/causeway/applib/annotation/Action.java
+++ b/api/applib/src/main/java/org/apache/causeway/applib/annotation/Action.java
@@ -213,5 +213,17 @@ public @interface Action {
     String fileAccept()
             default "";
 
+    /**
+     * Returns an alternative id for the action, using only ASCII characters.
+     *
+     * <p>
+     *     Although Java itself allows the full UTF character set for 
identifiers, some integrations (such as GraphQL)
+     *     have restrictions to only allow a more limited set of characters, 
in essence ASCII.
+     *     This attribute allows a version of the action's Id using only the 
ASCII character set to be provided.
+     * </p>
+     *
+     * @return an alternative id for the action, using only ASCII characters.
+     */
+    String asciiId() default "";
 
 }
diff --git 
a/api/applib/src/main/java/org/apache/causeway/applib/annotation/Collection.java
 
b/api/applib/src/main/java/org/apache/causeway/applib/annotation/Collection.java
index 5f8837dcb6..01b9ae8089 100644
--- 
a/api/applib/src/main/java/org/apache/causeway/applib/annotation/Collection.java
+++ 
b/api/applib/src/main/java/org/apache/causeway/applib/annotation/Collection.java
@@ -95,4 +95,17 @@ public @interface Collection {
     Class<?> typeOf()
             default void.class; // represents unspecified
 
+    /**
+     * Returns an alternative id for the collection, using only ASCII 
characters.
+     *
+     * <p>
+     *     Although Java itself allows the full UTF character set for 
identifiers, some integrations (such as GraphQL)
+     *     have restrictions to only allow a more limited set of characters, 
in essence ASCII.
+     *     This attribute allows a version of the collection's Id using only 
the ASCII character set to be provided.
+     * </p>
+     *
+     * @return an alternative id for the collection, using only ASCII 
characters.
+     */
+    String asciiId() default "";
+
 }
diff --git 
a/api/applib/src/main/java/org/apache/causeway/applib/annotation/Parameter.java 
b/api/applib/src/main/java/org/apache/causeway/applib/annotation/Parameter.java
index d825be3d3e..207fd6390b 100644
--- 
a/api/applib/src/main/java/org/apache/causeway/applib/annotation/Parameter.java
+++ 
b/api/applib/src/main/java/org/apache/causeway/applib/annotation/Parameter.java
@@ -142,4 +142,17 @@ public @interface Parameter {
     PrecedingParamsPolicy precedingParamsPolicy()
             default PrecedingParamsPolicy.AS_CONFIGURED;
 
+    /**
+     * Returns an alternative id for the parameter, using only ASCII 
characters.
+     *
+     * <p>
+     *     Although Java itself allows the full UTF character set for 
identifiers, some integrations (such as GraphQL)
+     *     have restrictions to only allow a more limited set of characters, 
in essence ASCII.
+     *     This attribute allows a version of the parameter's Id using only 
the ASCII character set to be provided.
+     * </p>
+     *
+     * @return an alternative id for the parameter, using only ASCII 
characters.
+     */
+    String asciiId() default "";
+
 }
diff --git 
a/api/applib/src/main/java/org/apache/causeway/applib/annotation/Property.java 
b/api/applib/src/main/java/org/apache/causeway/applib/annotation/Property.java
index bb3cabcf5b..432fa9f047 100644
--- 
a/api/applib/src/main/java/org/apache/causeway/applib/annotation/Property.java
+++ 
b/api/applib/src/main/java/org/apache/causeway/applib/annotation/Property.java
@@ -290,4 +290,16 @@ public @interface Property {
     String regexPatternReplacement()
             default "Doesn't match pattern";
 
+    /**
+     * Returns an alternative id for the property, using only ASCII characters.
+     *
+     * <p>
+     *     Although Java itself allows the full UTF character set for 
identifiers, some integrations (such as GraphQL)
+     *     have restrictions to only allow a more limited set of characters, 
in essence ASCII.
+     *     This attribute allows a version of the property's Id using only the 
ASCII character set to be provided.
+     * </p>
+     *
+     * @return an alternative id for the property, using only ASCII characters.
+     */
+    String asciiId() default "";
 }
diff --git a/core/metamodel/src/main/java/module-info.java 
b/core/metamodel/src/main/java/module-info.java
index e3f8907630..f8b25dc9d0 100644
--- a/core/metamodel/src/main/java/module-info.java
+++ b/core/metamodel/src/main/java/module-info.java
@@ -145,6 +145,7 @@ open module org.apache.causeway.core.metamodel {
     exports org.apache.causeway.core.metamodel.services.grid.spi;
     exports org.apache.causeway.core.metamodel.facets.object.layout;
     exports org.apache.causeway.core.metamodel.facets.all.hide;
+    exports org.apache.causeway.core.metamodel.facets.all.ascii;
 
     requires jakarta.activation;
     requires java.annotation;
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/ActionAnnotationFacetFactory.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/ActionAnnotationFacetFactory.java
index c3b6272925..8894cf93e6 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/ActionAnnotationFacetFactory.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/action/ActionAnnotationFacetFactory.java
@@ -37,6 +37,7 @@ import 
org.apache.causeway.core.metamodel.facets.actions.action.invocation.Actio
 import 
org.apache.causeway.core.metamodel.facets.actions.action.prototype.PrototypeFacetForActionAnnotation;
 import 
org.apache.causeway.core.metamodel.facets.actions.action.semantics.ActionSemanticsFacetForActionAnnotation;
 import 
org.apache.causeway.core.metamodel.facets.actions.action.typeof.TypeOfFacetForActionAnnotation;
+import 
org.apache.causeway.core.metamodel.facets.actions.ascii.AsciiFacetForActionAnnotation;
 import 
org.apache.causeway.core.metamodel.facets.actions.fileaccept.FileAcceptFacetForActionAnnotation;
 import 
org.apache.causeway.core.metamodel.facets.members.layout.group.LayoutGroupFacetForActionAnnotation;
 import 
org.apache.causeway.core.metamodel.facets.members.publish.command.CommandPublishingFacetForActionAnnotation;
@@ -73,6 +74,7 @@ extends FacetFactoryAbstract {
         processChoicesFrom(processMethodContext, actionIfAny);
 
         processFileAccept(processMethodContext, actionIfAny);
+        processAsciiName(processMethodContext, actionIfAny);
     }
 
     Optional<Action> actionIfAny(final ProcessMethodContext 
processMethodContext) {
@@ -251,5 +253,15 @@ extends FacetFactoryAbstract {
                 .create(actionIfAny, holder));
     }
 
+    void processAsciiName(final ProcessMethodContext processMethodContext, 
final Optional<Action> actionIfAny) {
+
+        val holder = processMethodContext.getFacetHolder();
+
+        // check for @Action(ascii=...)
+        addFacetIfPresent(
+                AsciiFacetForActionAnnotation
+                .create(actionIfAny, holder));
+    }
+
 
 }
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/ascii/AsciiFacetForActionAnnotation.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/ascii/AsciiFacetForActionAnnotation.java
new file mode 100644
index 0000000000..512dcbcfd9
--- /dev/null
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/actions/ascii/AsciiFacetForActionAnnotation.java
@@ -0,0 +1,46 @@
+/*
+ *  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.causeway.core.metamodel.facets.actions.ascii;
+
+import java.util.Optional;
+
+import org.apache.causeway.applib.annotation.Action;
+import org.apache.causeway.commons.internal.base._Strings;
+import org.apache.causeway.core.metamodel.facetapi.FacetHolder;
+import 
org.apache.causeway.core.metamodel.facets.objectvalue.fileaccept.FileAcceptFacet;
+import 
org.apache.causeway.core.metamodel.facets.objectvalue.fileaccept.FileAcceptFacetAbstract;
+
+public class AsciiFacetForActionAnnotation
+extends FileAcceptFacetAbstract {
+
+    public static Optional<FileAcceptFacet> create(
+            final Optional<Action> actionIfAny,
+            final FacetHolder holder) {
+
+        return actionIfAny
+                .map(Action::asciiId)
+                .filter(_Strings::isNotEmpty)
+                .map(asciiName -> new AsciiFacetForActionAnnotation(asciiName, 
holder));
+    }
+
+    private AsciiFacetForActionAnnotation(final String value, final 
FacetHolder holder) {
+        super(value, holder);
+    }
+
+}
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/ascii/AsciiFacet.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/ascii/AsciiFacet.java
new file mode 100644
index 0000000000..c3775bba00
--- /dev/null
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/ascii/AsciiFacet.java
@@ -0,0 +1,29 @@
+/*
+ *  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.causeway.core.metamodel.facets.all.ascii;
+
+import org.apache.causeway.core.metamodel.facetapi.Facet;
+
+public interface AsciiFacet
+extends
+    Facet {
+
+    String asciiId();
+
+}
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/ascii/AsciiFacetAbstract.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/ascii/AsciiFacetAbstract.java
new file mode 100644
index 0000000000..34f276ca52
--- /dev/null
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/all/ascii/AsciiFacetAbstract.java
@@ -0,0 +1,48 @@
+/*
+ *  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.causeway.core.metamodel.facets.all.ascii;
+
+import org.apache.causeway.core.metamodel.facetapi.FacetAbstract;
+import org.apache.causeway.core.metamodel.facetapi.FacetHolder;
+
+/**
+ * @since 2.0
+ */
+public abstract class AsciiFacetAbstract
+extends FacetAbstract
+implements AsciiFacet {
+
+    private final String asciiName;
+
+    public static final Class<AsciiFacet> type() {
+        return AsciiFacet.class;
+    }
+
+    protected AsciiFacetAbstract(
+            final String asciiName,
+            final FacetHolder holder) {
+        super(type(), holder, Precedence.DEFAULT);
+        this.asciiName = asciiName;
+    }
+
+    @Override
+    public String asciiId() {
+        return asciiName;
+    }
+}
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/collections/collection/CollectionAnnotationFacetFactory.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/collections/collection/CollectionAnnotationFacetFactory.java
index 6e2f390432..158d314ca5 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/collections/collection/CollectionAnnotationFacetFactory.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/collections/collection/CollectionAnnotationFacetFactory.java
@@ -22,6 +22,7 @@ import java.util.Optional;
 
 import javax.inject.Inject;
 
+import org.apache.causeway.applib.annotation.Action;
 import org.apache.causeway.applib.annotation.Collection;
 import org.apache.causeway.applib.annotation.SemanticsOf;
 import org.apache.causeway.commons.semantics.CollectionSemantics;
@@ -30,8 +31,10 @@ import 
org.apache.causeway.core.metamodel.facetapi.FeatureType;
 import org.apache.causeway.core.metamodel.facets.FacetFactoryAbstract;
 import org.apache.causeway.core.metamodel.facets.FacetedMethod;
 import org.apache.causeway.core.metamodel.facets.actcoll.typeof.TypeOfFacet;
+import 
org.apache.causeway.core.metamodel.facets.actions.ascii.AsciiFacetForActionAnnotation;
 import 
org.apache.causeway.core.metamodel.facets.actions.contributing.ContributingFacetAbstract;
 import 
org.apache.causeway.core.metamodel.facets.actions.semantics.ActionSemanticsFacetAbstract;
+import 
org.apache.causeway.core.metamodel.facets.collections.collection.ascii.AsciiFacetForCollectionAnnotation;
 import 
org.apache.causeway.core.metamodel.facets.collections.collection.modify.CollectionDomainEventFacet;
 import 
org.apache.causeway.core.metamodel.facets.collections.collection.typeof.TypeOfFacetForCollectionAnnotation;
 import 
org.apache.causeway.core.metamodel.facets.propcoll.accessor.PropertyOrCollectionAccessorFacet;
@@ -60,6 +63,7 @@ extends FacetFactoryAbstract {
 
         processDomainEvent(processMethodContext, collectionIfAny);
         processTypeOf(processMethodContext, collectionIfAny);
+        processAsciiName(processMethodContext, collectionIfAny);
     }
 
     Optional<Collection> collectionIfAny(final ProcessMethodContext 
processMethodContext) {
@@ -122,4 +126,14 @@ extends FacetFactoryAbstract {
         });
     }
 
+    void processAsciiName(final ProcessMethodContext processMethodContext, 
final Optional<Collection> collectionIfAny) {
+
+        val holder = processMethodContext.getFacetHolder();
+
+        // check for @Collection(asciiId=...)
+        addFacetIfPresent(
+                AsciiFacetForCollectionAnnotation
+                        .create(collectionIfAny, holder));
+    }
+
 }
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/collections/collection/ascii/AsciiFacetForCollectionAnnotation.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/collections/collection/ascii/AsciiFacetForCollectionAnnotation.java
new file mode 100644
index 0000000000..0d1489241b
--- /dev/null
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/collections/collection/ascii/AsciiFacetForCollectionAnnotation.java
@@ -0,0 +1,48 @@
+/*
+ *  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.causeway.core.metamodel.facets.collections.collection.ascii;
+
+import java.util.Optional;
+
+import org.apache.causeway.applib.annotation.Collection;
+import org.apache.causeway.commons.internal.base._Strings;
+import org.apache.causeway.core.metamodel.facetapi.FacetHolder;
+import org.apache.causeway.core.metamodel.facets.FacetedMethod;
+import org.apache.causeway.core.metamodel.facets.all.ascii.AsciiFacet;
+import org.apache.causeway.core.metamodel.facets.all.ascii.AsciiFacetAbstract;
+
+public class AsciiFacetForCollectionAnnotation
+extends AsciiFacetAbstract {
+
+    public static Optional<AsciiFacet> create(
+            final Optional<Collection> collectionIfAny,
+            final FacetedMethod facetHolder) {
+
+        return collectionIfAny
+                .map(Collection::asciiId)
+                .filter(_Strings::isNotEmpty)
+                .map(asciiName -> new 
AsciiFacetForCollectionAnnotation(asciiName, facetHolder));
+    }
+
+    private AsciiFacetForCollectionAnnotation(
+            final String value, final FacetHolder holder) {
+        super(value, holder);
+    }
+
+}
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/ascii/AsciiFacetForParameterAnnotation.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/ascii/AsciiFacetForParameterAnnotation.java
new file mode 100644
index 0000000000..664ba0223c
--- /dev/null
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/ascii/AsciiFacetForParameterAnnotation.java
@@ -0,0 +1,47 @@
+/*
+ *  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.causeway.core.metamodel.facets.param.ascii;
+
+import java.util.Optional;
+
+import org.apache.causeway.applib.annotation.Parameter;
+import org.apache.causeway.commons.internal.base._Strings;
+import org.apache.causeway.core.metamodel.facetapi.FacetHolder;
+import org.apache.causeway.core.metamodel.facets.all.ascii.AsciiFacet;
+import org.apache.causeway.core.metamodel.facets.all.ascii.AsciiFacetAbstract;
+
+public class AsciiFacetForParameterAnnotation
+extends AsciiFacetAbstract {
+
+    public static Optional<AsciiFacet> create(
+            final Optional<Parameter> collectionIfAny,
+            final FacetHolder facetHolder) {
+
+        return collectionIfAny
+                .map(Parameter::asciiId)
+                .filter(_Strings::isNotEmpty)
+                .map(asciiName -> new 
AsciiFacetForParameterAnnotation(asciiName, facetHolder));
+    }
+
+    private AsciiFacetForParameterAnnotation(
+            final String value, final FacetHolder holder) {
+        super(value, holder);
+    }
+
+}
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/parameter/ParameterAnnotationFacetFactory.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/parameter/ParameterAnnotationFacetFactory.java
index d224e6f1f3..00f5179d55 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/parameter/ParameterAnnotationFacetFactory.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/param/parameter/ParameterAnnotationFacetFactory.java
@@ -25,6 +25,7 @@ import org.apache.causeway.applib.annotation.Parameter;
 import org.apache.causeway.core.metamodel.context.MetaModelContext;
 import org.apache.causeway.core.metamodel.facetapi.FeatureType;
 import org.apache.causeway.core.metamodel.facets.FacetFactoryAbstract;
+import 
org.apache.causeway.core.metamodel.facets.param.ascii.AsciiFacetForParameterAnnotation;
 import 
org.apache.causeway.core.metamodel.facets.param.parameter.fileaccept.FileAcceptFacetForParameterAnnotation;
 import 
org.apache.causeway.core.metamodel.facets.param.parameter.mandatory.MandatoryFacetForParameterAnnotation;
 import 
org.apache.causeway.core.metamodel.facets.param.parameter.mandatory.MandatoryFacetInvertedByNullableAnnotationOnParameter;
@@ -52,6 +53,7 @@ extends FacetFactoryAbstract {
         processParamsRegEx(processParameterContext);
         processParamsOptional(processParameterContext);
         processParamsFileAccept(processParameterContext);
+        processParamsAsciiName(processParameterContext);
     }
 
     // check for @Parameter(precedingParamsPolicy=...)
@@ -132,5 +134,16 @@ extends FacetFactoryAbstract {
                 .create(parameterIfAny, holder));
     }
 
+    void processParamsAsciiName(final ProcessParameterContext 
processParameterContext) {
+
+        val holder = processParameterContext.getFacetHolder();
+        val parameterIfAny = 
processParameterContext.synthesizeOnParameter(Parameter.class);
+
+        // check for @Parameter(asciiId=...)
+        addFacetIfPresent(
+                AsciiFacetForParameterAnnotation
+                        .create(parameterIfAny, holder));
+    }
+
 
 }
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/ascii/AsciiFacetForPropertyAnnotation.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/ascii/AsciiFacetForPropertyAnnotation.java
new file mode 100644
index 0000000000..b7e8301506
--- /dev/null
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/ascii/AsciiFacetForPropertyAnnotation.java
@@ -0,0 +1,48 @@
+/*
+ *  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.causeway.core.metamodel.facets.properties.ascii;
+
+import java.util.Optional;
+
+import org.apache.causeway.applib.annotation.Property;
+import org.apache.causeway.commons.internal.base._Strings;
+import org.apache.causeway.core.metamodel.facetapi.FacetHolder;
+import org.apache.causeway.core.metamodel.facets.FacetedMethod;
+import org.apache.causeway.core.metamodel.facets.all.ascii.AsciiFacet;
+import org.apache.causeway.core.metamodel.facets.all.ascii.AsciiFacetAbstract;
+
+public class AsciiFacetForPropertyAnnotation
+extends AsciiFacetAbstract {
+
+    public static Optional<AsciiFacet> create(
+            final Optional<Property> collectionIfAny,
+            final FacetedMethod facetHolder) {
+
+        return collectionIfAny
+                .map(Property::asciiId)
+                .filter(_Strings::isNotEmpty)
+                .map(asciiName -> new 
AsciiFacetForPropertyAnnotation(asciiName, facetHolder));
+    }
+
+    private AsciiFacetForPropertyAnnotation(
+            final String value, final FacetHolder holder) {
+        super(value, holder);
+    }
+
+}
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/property/PropertyAnnotationFacetFactory.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/property/PropertyAnnotationFacetFactory.java
index bb4ce0690f..71da209f8d 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/property/PropertyAnnotationFacetFactory.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/facets/properties/property/PropertyAnnotationFacetFactory.java
@@ -23,6 +23,7 @@ import java.util.Optional;
 import javax.inject.Inject;
 import javax.validation.constraints.Pattern;
 
+import org.apache.causeway.applib.annotation.Collection;
 import org.apache.causeway.applib.annotation.Property;
 import org.apache.causeway.applib.annotation.SemanticsOf;
 import org.apache.causeway.applib.mixins.system.HasInteractionId;
@@ -32,11 +33,13 @@ import 
org.apache.causeway.core.metamodel.facets.FacetFactoryAbstract;
 import org.apache.causeway.core.metamodel.facets.FacetedMethod;
 import 
org.apache.causeway.core.metamodel.facets.actions.contributing.ContributingFacetAbstract;
 import 
org.apache.causeway.core.metamodel.facets.actions.semantics.ActionSemanticsFacetAbstract;
+import 
org.apache.causeway.core.metamodel.facets.collections.collection.ascii.AsciiFacetForCollectionAnnotation;
 import 
org.apache.causeway.core.metamodel.facets.members.publish.command.CommandPublishingFacet;
 import 
org.apache.causeway.core.metamodel.facets.members.publish.command.CommandPublishingFacetForPropertyAnnotation;
 import 
org.apache.causeway.core.metamodel.facets.members.publish.execution.ExecutionPublishingFacet;
 import 
org.apache.causeway.core.metamodel.facets.members.publish.execution.ExecutionPublishingFacetForPropertyAnnotation;
 import 
org.apache.causeway.core.metamodel.facets.propcoll.accessor.PropertyOrCollectionAccessorFacet;
+import 
org.apache.causeway.core.metamodel.facets.properties.ascii.AsciiFacetForPropertyAnnotation;
 import 
org.apache.causeway.core.metamodel.facets.properties.projection.ProjectingFacetFromPropertyAnnotation;
 import 
org.apache.causeway.core.metamodel.facets.properties.property.disabled.DisabledFacetForPropertyAnnotation;
 import 
org.apache.causeway.core.metamodel.facets.properties.property.entitychangepublishing.EntityPropertyChangePublishingPolicyFacetForPropertyAnnotation;
@@ -88,6 +91,7 @@ extends FacetFactoryAbstract {
         processOptional(processMethodContext, propertyIfAny);
         processRegEx(processMethodContext, propertyIfAny);
         processFileAccept(processMethodContext, propertyIfAny);
+        processAsciiName(processMethodContext, propertyIfAny);
     }
 
     Optional<Property> propertyIfAny(final ProcessMethodContext 
processMethodContext) {
@@ -323,4 +327,15 @@ extends FacetFactoryAbstract {
                 .create(propertyIfAny, holder));
     }
 
+
+    void processAsciiName(final ProcessMethodContext processMethodContext, 
final Optional<Property> propertyIfAny) {
+
+        val holder = processMethodContext.getFacetHolder();
+
+        // check for @Property(asciiId=...)
+        addFacetIfPresent(
+                AsciiFacetForPropertyAnnotation
+                        .create(propertyIfAny, holder));
+    }
+
 }
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/ObjectActionParameterAbstract.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/ObjectActionParameterAbstract.java
index 74a5774ac2..8bf6b76240 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/ObjectActionParameterAbstract.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/specimpl/ObjectActionParameterAbstract.java
@@ -31,6 +31,7 @@ import org.apache.causeway.core.metamodel.consent.Consent;
 import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.causeway.core.metamodel.facetapi.FacetHolder;
 import org.apache.causeway.core.metamodel.facetapi.FeatureType;
+import org.apache.causeway.core.metamodel.facets.all.ascii.AsciiFacet;
 import 
org.apache.causeway.core.metamodel.facets.all.described.ParamDescribedFacet;
 import org.apache.causeway.core.metamodel.facets.all.named.ParamNamedFacet;
 import 
org.apache.causeway.core.metamodel.facets.param.autocomplete.ActionParameterAutoCompleteFacet;
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/TypeNames.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/TypeNames.java
index a0b28bbdf9..7ea62fc73d 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/TypeNames.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/TypeNames.java
@@ -24,6 +24,7 @@ import 
org.apache.causeway.core.metamodel.spec.feature.ObjectActionParameter;
 import org.apache.causeway.core.metamodel.spec.feature.ObjectMember;
 import org.apache.causeway.core.metamodel.spec.feature.OneToManyAssociation;
 import org.apache.causeway.core.metamodel.spec.feature.OneToOneAssociation;
+import 
org.apache.causeway.viewer.graphql.model.domain.common.query.ObjectFeatureUtils;
 
 import lombok.experimental.UtilityClass;
 
@@ -61,65 +62,65 @@ public final class TypeNames {
 
     public static String actionTypeNameFor(
             final ObjectSpecification owningType,
-            final ObjectAction objectAction,
+            final ObjectAction oa,
             final SchemaType schemaType) {
-        return objectTypeNameFor(owningType, schemaType) + "__" + 
objectAction.getId() + "__gqlv_action";
+        return objectTypeNameFor(owningType, schemaType) + "__" + 
ObjectFeatureUtils.asciiIdFor(oa) + "__gqlv_action";
     }
 
     public static String actionInvokeTypeNameFor(
             final ObjectSpecification owningType,
-            final ObjectAction objectAction,
+            final ObjectAction oa,
             final SchemaType schemaType) {
-        return objectTypeNameFor(owningType, schemaType) + "__" + 
objectAction.getId() + "__gqlv_action_invoke";
+        return objectTypeNameFor(owningType, schemaType) + "__" + 
ObjectFeatureUtils.asciiIdFor(oa) + "__gqlv_action_invoke";
     }
 
     public static String actionParamsTypeNameFor(
             final ObjectSpecification owningType,
-            final ObjectAction objectAction,
+            final ObjectAction oa,
             final SchemaType schemaType) {
-        return objectTypeNameFor(owningType, schemaType) + "__" + 
objectAction.getId() + "__gqlv_action_params";
+        return objectTypeNameFor(owningType, schemaType) + "__" + 
ObjectFeatureUtils.asciiIdFor(oa) + "__gqlv_action_params";
     }
 
     public static String actionArgsTypeNameFor(
             final ObjectSpecification owningType,
-            final ObjectAction objectAction,
+            final ObjectAction oa,
             final SchemaType schemaType) {
-        return objectTypeNameFor(owningType, schemaType) + "__" + 
objectAction.getId() + "__gqlv_action_args";
+        return objectTypeNameFor(owningType, schemaType) + "__" + 
ObjectFeatureUtils.asciiIdFor(oa) + "__gqlv_action_args";
     }
 
     public static String actionParamTypeNameFor(
             final ObjectSpecification owningType,
-            final ObjectActionParameter objectActionParameter,
+            final ObjectActionParameter oap,
             final SchemaType schemaType) {
-        return objectTypeNameFor(owningType, schemaType) + "__" + 
objectActionParameter.getAction().getId() + "__" + 
objectActionParameter.getId() + "__gqlv_action_parameter";
+        return objectTypeNameFor(owningType, schemaType) + "__" + 
ObjectFeatureUtils.asciiIdFor(oap.getAction()) + "__" + 
ObjectFeatureUtils.asciiIdFor(oap) + "__gqlv_action_parameter";
     }
 
     public static String propertyTypeNameFor(
             final ObjectSpecification owningType,
-            final OneToOneAssociation oneToOneAssociation,
+            final OneToOneAssociation otoa,
             final SchemaType schemaType) {
-        return objectTypeNameFor(owningType, schemaType) + "__" + 
oneToOneAssociation.getId() + "__gqlv_property";
+        return objectTypeNameFor(owningType, schemaType) + "__" + 
ObjectFeatureUtils.asciiIdFor(otoa) + "__gqlv_property";
     }
 
     public static String propertyLobTypeNameFor(
             final ObjectSpecification owningType,
-            final OneToOneAssociation oneToOneAssociation,
+            final OneToOneAssociation otoa,
             final SchemaType schemaType) {
-        return objectTypeNameFor(owningType, schemaType) + "__" + 
oneToOneAssociation.getId() + "__gqlv_property_lob";
+        return objectTypeNameFor(owningType, schemaType) + "__" + 
ObjectFeatureUtils.asciiIdFor(otoa) + "__gqlv_property_lob";
     }
 
     public static String collectionTypeNameFor(
             final ObjectSpecification owningType,
-            final OneToManyAssociation objectMember,
+            final OneToManyAssociation otma,
             final SchemaType schemaType) {
-        return objectTypeNameFor(owningType, schemaType) + "__" + 
objectMember.getId() + "__gqlv_collection";
+        return objectTypeNameFor(owningType, schemaType) + "__" + 
ObjectFeatureUtils.asciiIdFor(otma) + "__gqlv_collection";
     }
 
     public static String memberTypeNameFor(
             final ObjectSpecification owningType,
             final ObjectMember objectMember,
             final SchemaType schemaType) {
-        return objectTypeNameFor(owningType, schemaType) + "__" + 
objectMember.getId() + "__gqlv_member";
+        return objectTypeNameFor(owningType, schemaType) + "__" + 
ObjectFeatureUtils.asciiIdFor(objectMember) + "__gqlv_member";
     }
 
     private static String sanitized(final String name) {
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/common/query/CommonDomainObject.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/common/query/CommonDomainObject.java
index b89c86adaa..bb06f934fe 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/common/query/CommonDomainObject.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/common/query/CommonDomainObject.java
@@ -190,7 +190,7 @@ public class CommonDomainObject
     @Override
     protected Object fetchData(DataFetchingEnvironment 
dataFetchingEnvironment) {
         Object target = dataFetchingEnvironment.getArgument("object");
-        return CommonActionUtils.asPojo(getObjectSpecification(), target, new 
Environment.For(dataFetchingEnvironment), context)
+        return ObjectFeatureUtils.asPojo(getObjectSpecification(), target, new 
Environment.For(dataFetchingEnvironment), context)
                 .orElse(null);
     }
 
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/common/query/CommonActionUtils.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/common/query/ObjectFeatureUtils.java
similarity index 93%
rename from 
viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/common/query/CommonActionUtils.java
rename to 
viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/common/query/ObjectFeatureUtils.java
index 7f4709b2e7..6001d9fedf 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/common/query/CommonActionUtils.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/common/query/ObjectFeatureUtils.java
@@ -25,10 +25,12 @@ import java.util.stream.Collectors;
 
 import org.apache.causeway.applib.services.bookmark.Bookmark;
 import org.apache.causeway.commons.collections.Can;
+import org.apache.causeway.core.metamodel.facets.all.ascii.AsciiFacet;
 import org.apache.causeway.core.metamodel.object.ManagedObject;
 import org.apache.causeway.core.metamodel.spec.ObjectSpecification;
 import org.apache.causeway.core.metamodel.spec.feature.ObjectAction;
 import org.apache.causeway.core.metamodel.spec.feature.ObjectActionParameter;
+import org.apache.causeway.core.metamodel.spec.feature.ObjectFeature;
 import org.apache.causeway.viewer.graphql.model.context.Context;
 import org.apache.causeway.viewer.graphql.model.domain.Environment;
 import org.apache.causeway.viewer.graphql.model.fetcher.BookmarkedPojo;
@@ -37,7 +39,7 @@ import lombok.experimental.UtilityClass;
 import lombok.val;
 
 @UtilityClass
-public class CommonActionUtils {
+public class ObjectFeatureUtils {
 
     public static Optional<Object> asPojo(
             final ObjectSpecification elementType,
@@ -108,7 +110,7 @@ public class CommonActionUtils {
         return parameters
                 .map(oap -> {
                     final ObjectSpecification elementType = 
oap.getElementType();
-                    Object argumentValue = argumentPojos.get(oap.getId());
+                    Object argumentValue = argumentPojos.get(asciiIdFor(oap));
                     Object pojoOrPojoList;
 
                     switch (elementType.getBeanSort()) {
@@ -151,6 +153,11 @@ public class CommonActionUtils {
                 });
     }
 
+    public static String asciiIdFor(final ObjectFeature objectFeature) {
+        val asciiFacet = objectFeature.getFacet(AsciiFacet.class);
+        return asciiFacet != null ? asciiFacet.asciiId() : 
objectFeature.getId();
+    }
+
     private static ManagedObject adaptValue(
             final ObjectActionParameter oap,
             final Object argumentValue,
@@ -166,6 +173,7 @@ public class CommonActionUtils {
     }
 
     public static String keyFor(String ref) {
-        return CommonActionUtils.class.getName() + "#" + ref;
+        return ObjectFeatureUtils.class.getName() + "#" + ref;
     }
+
 }
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/common/query/meta/CommonMetaSaveAs.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/common/query/meta/CommonMetaSaveAs.java
index 8e0c645c96..3282364d9f 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/common/query/meta/CommonMetaSaveAs.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/common/query/meta/CommonMetaSaveAs.java
@@ -27,7 +27,7 @@ import static 
graphql.schema.GraphQLFieldDefinition.newFieldDefinition;
 
 import org.apache.causeway.viewer.graphql.model.context.Context;
 import org.apache.causeway.viewer.graphql.model.domain.Element;
-import 
org.apache.causeway.viewer.graphql.model.domain.common.query.CommonActionUtils;
+import 
org.apache.causeway.viewer.graphql.model.domain.common.query.ObjectFeatureUtils;
 import org.apache.causeway.viewer.graphql.model.fetcher.BookmarkedPojo;
 
 public class CommonMetaSaveAs extends Element {
@@ -49,7 +49,7 @@ public class CommonMetaSaveAs extends Element {
     protected Object fetchData(DataFetchingEnvironment environment) {
         String ref = environment.getArgument("ref");
         CommonMetaFetcher source = environment.getSource();
-        String originalKey = CommonActionUtils.keyFor(ref);
+        String originalKey = ObjectFeatureUtils.keyFor(ref);
         GraphQLContext graphQlContext = environment.getGraphQlContext();
 
         // we ensure the key hasn't been used already
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/mutation/RichMutationForAction.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/mutation/RichMutationForAction.java
index c007ca4bc0..057634f681 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/mutation/RichMutationForAction.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/mutation/RichMutationForAction.java
@@ -49,7 +49,7 @@ import 
org.apache.causeway.viewer.graphql.model.domain.Environment;
 import org.apache.causeway.viewer.graphql.model.domain.Element;
 import org.apache.causeway.viewer.graphql.model.domain.SchemaType;
 import org.apache.causeway.viewer.graphql.model.domain.TypeNames;
-import 
org.apache.causeway.viewer.graphql.model.domain.common.query.CommonActionUtils;
+import 
org.apache.causeway.viewer.graphql.model.domain.common.query.ObjectFeatureUtils;
 import org.apache.causeway.viewer.graphql.model.domain.rich.query.RichAction;
 import org.apache.causeway.viewer.graphql.model.exceptions.DisabledException;
 import org.apache.causeway.viewer.graphql.model.exceptions.HiddenException;
@@ -92,8 +92,8 @@ public class RichMutationForAction extends Element {
 
     private static String fieldName(
             final ObjectSpecification objectSpecification,
-            final ObjectAction objectAction) {
-        return TypeNames.objectTypeFieldNameFor(objectSpecification) + "__" + 
objectAction.getId();
+            final ObjectAction oa) {
+        return TypeNames.objectTypeFieldNameFor(objectSpecification) + "__" + 
ObjectFeatureUtils.asciiIdFor(oa);
     }
 
     @Nullable
@@ -157,7 +157,7 @@ public class RichMutationForAction extends Element {
             } else {
                 val refValue = (String)argumentValue.get("ref");
                 if (refValue != null) {
-                    String key = CommonActionUtils.keyFor(refValue);
+                    String key = ObjectFeatureUtils.keyFor(refValue);
                     BookmarkedPojo value = ((Environment) 
environment).getGraphQlContext().get(key);
                     result = 
Optional.of(value).map(BookmarkedPojo::getTargetPojo);
                 } else {
@@ -227,18 +227,18 @@ public class RichMutationForAction extends Element {
     }
 
     // adapted from SimpleAction
-    GraphQLArgument gqlArgumentFor(final OneToOneActionParameter 
oneToOneActionParameter) {
+    GraphQLArgument gqlArgumentFor(final OneToOneActionParameter otoap) {
         return GraphQLArgument.newArgument()
-                .name(oneToOneActionParameter.getId())
-                .type(context.typeMapper.inputTypeFor(oneToOneActionParameter, 
TypeMapper.InputContext.INVOKE, SchemaType.RICH))
+                .name(ObjectFeatureUtils.asciiIdFor(otoap))
+                .type(context.typeMapper.inputTypeFor(otoap, 
TypeMapper.InputContext.INVOKE, SchemaType.RICH))
                 .build();
     }
 
     // adapted from SimpleAction
-    GraphQLArgument gqlArgumentFor(final OneToManyActionParameter 
oneToManyActionParameter) {
+    GraphQLArgument gqlArgumentFor(final OneToManyActionParameter otmap) {
         return GraphQLArgument.newArgument()
-                .name(oneToManyActionParameter.getId())
-                
.type(context.typeMapper.inputTypeFor(oneToManyActionParameter, 
SchemaType.RICH))
+                .name(ObjectFeatureUtils.asciiIdFor(otmap))
+                .type(context.typeMapper.inputTypeFor(otmap, SchemaType.RICH))
                 .build();
     }
 
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/mutation/RichMutationForProperty.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/mutation/RichMutationForProperty.java
index eced3b7d74..eedce83511 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/mutation/RichMutationForProperty.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/mutation/RichMutationForProperty.java
@@ -39,7 +39,7 @@ import 
org.apache.causeway.viewer.graphql.model.domain.Environment;
 import org.apache.causeway.viewer.graphql.model.domain.Element;
 import org.apache.causeway.viewer.graphql.model.domain.SchemaType;
 import org.apache.causeway.viewer.graphql.model.domain.TypeNames;
-import 
org.apache.causeway.viewer.graphql.model.domain.common.query.CommonActionUtils;
+import 
org.apache.causeway.viewer.graphql.model.domain.common.query.ObjectFeatureUtils;
 import org.apache.causeway.viewer.graphql.model.exceptions.DisabledException;
 import org.apache.causeway.viewer.graphql.model.exceptions.HiddenException;
 import org.apache.causeway.viewer.graphql.model.exceptions.InvalidException;
@@ -81,8 +81,8 @@ public class RichMutationForProperty extends Element {
 
     private static String fieldName(
             final ObjectSpecification objectSpecification,
-            final OneToOneAssociation oneToOneAssociation) {
-        return TypeNames.objectTypeFieldNameFor(objectSpecification) + "__" + 
oneToOneAssociation.getId();
+            final OneToOneAssociation otoa) {
+        return TypeNames.objectTypeFieldNameFor(objectSpecification) + "__" + 
ObjectFeatureUtils.asciiIdFor(otoa);
     }
 
     @Override
@@ -110,7 +110,7 @@ public class RichMutationForProperty extends Element {
         } else {
             val refValue = (String)argumentValue1.get("ref");
             if (refValue != null) {
-                val key = CommonActionUtils.keyFor(refValue);
+                val key = ObjectFeatureUtils.keyFor(refValue);
                 BookmarkedPojo value = 
environment.getGraphQlContext().get(key);
                 result = Optional.of(value).map(BookmarkedPojo::getTargetPojo);
             } else {
@@ -123,7 +123,7 @@ public class RichMutationForProperty extends Element {
         val managedObject = ManagedObject.adaptSingular(objectSpec, 
sourcePojo);
 
         Map<String, Object> arguments = dataFetchingEnvironment.getArguments();
-        Object argumentValue = arguments.get(oneToOneAssociation.getId());
+        Object argumentValue = 
arguments.get(ObjectFeatureUtils.asciiIdFor(oneToOneAssociation));
         ManagedObject argumentManagedObject = 
ManagedObject.adaptProperty(oneToOneAssociation, argumentValue);
 
         val visibleConsent = oneToOneAssociation.isVisible(managedObject, 
InteractionInitiatedBy.USER, Where.ANYWHERE);
@@ -160,7 +160,7 @@ public class RichMutationForProperty extends Element {
 
         fieldBuilder.argument(
                 GraphQLArgument.newArgument()
-                        .name(oneToOneAssociation.getId())
+                        
.name(ObjectFeatureUtils.asciiIdFor(oneToOneAssociation))
                         
.type(context.typeMapper.inputTypeFor(oneToOneAssociation, 
TypeMapper.InputContext.INVOKE, SchemaType.RICH))
                         .build());
     }
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichAction.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichAction.java
index 8d173fee24..13c11b55ba 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichAction.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichAction.java
@@ -42,7 +42,7 @@ import 
org.apache.causeway.viewer.graphql.model.domain.SchemaType;
 import org.apache.causeway.viewer.graphql.model.domain.TypeNames;
 import 
org.apache.causeway.viewer.graphql.model.domain.common.interactors.ActionInteractor;
 import 
org.apache.causeway.viewer.graphql.model.domain.common.interactors.ObjectInteractor;
-import 
org.apache.causeway.viewer.graphql.model.domain.common.query.CommonActionUtils;
+import 
org.apache.causeway.viewer.graphql.model.domain.common.query.ObjectFeatureUtils;
 import org.apache.causeway.viewer.graphql.model.fetcher.BookmarkedPojo;
 import org.apache.causeway.viewer.graphql.model.types.TypeMapper;
 
@@ -91,7 +91,7 @@ public class RichAction
                     : null);
         addChildFieldFor(this.params = new RichActionParams(this, context));
 
-        buildObjectTypeAndField(objectAction.getId(), 
objectAction.getCanonicalDescription().orElse(objectAction.getCanonicalFriendlyName()));
+        buildObjectTypeAndField(ObjectFeatureUtils.asciiIdFor(objectAction), 
objectAction.getCanonicalDescription().orElse(objectAction.getCanonicalFriendlyName()));
     }
 
     private boolean isInvokeAllowed(ObjectAction objectAction) {
@@ -132,7 +132,7 @@ public class RichAction
         return parameters
                 .map(oap -> {
                     final ObjectSpecification elementType = 
oap.getElementType();
-                    Object argumentValue = argumentPojos.get(oap.getId());
+                    Object argumentValue = 
argumentPojos.get(ObjectFeatureUtils.asciiIdFor(oap));
                     Object pojoOrPojoList;
 
                     switch (elementType.getBeanSort()) {
@@ -200,7 +200,7 @@ public class RichAction
 
         val refValue = (String)argumentValue.get("ref");
         if (refValue != null) {
-            String key = CommonActionUtils.keyFor(refValue);
+            String key = ObjectFeatureUtils.keyFor(refValue);
             BookmarkedPojo bookmarkedPojo = 
environment.getGraphQlContext().get(key);
             if (bookmarkedPojo == null) {
                 throw new IllegalArgumentException(String.format(
@@ -270,18 +270,18 @@ public class RichAction
     }
 
     GraphQLArgument gqlArgumentFor(
-            final OneToOneActionParameter oneToOneActionParameter,
+            final OneToOneActionParameter oap,
             final TypeMapper.InputContext inputContext) {
         return GraphQLArgument.newArgument()
-                .name(oneToOneActionParameter.getId())
-                .type(context.typeMapper.inputTypeFor(oneToOneActionParameter, 
inputContext, getSchemaType()))
+                .name(ObjectFeatureUtils.asciiIdFor(oap))
+                .type(context.typeMapper.inputTypeFor(oap, inputContext, 
getSchemaType()))
                 .build();
     }
 
-    GraphQLArgument gqlArgumentFor(final OneToManyActionParameter 
oneToManyActionParameter) {
+    GraphQLArgument gqlArgumentFor(final OneToManyActionParameter otmp) {
         return GraphQLArgument.newArgument()
-                .name(oneToManyActionParameter.getId())
-                
.type(context.typeMapper.inputTypeFor(oneToManyActionParameter, 
getSchemaType()))
+                .name(ObjectFeatureUtils.asciiIdFor(otmp))
+                .type(context.typeMapper.inputTypeFor(otmp, getSchemaType()))
                 .build();
     }
 
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionInvokeArgsArg.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionInvokeArgsArg.java
index a295b55852..0913b8446e 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionInvokeArgsArg.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionInvokeArgsArg.java
@@ -29,6 +29,7 @@ import 
org.apache.causeway.viewer.graphql.model.context.Context;
 import org.apache.causeway.viewer.graphql.model.domain.Environment;
 import org.apache.causeway.viewer.graphql.model.domain.Element;
 import 
org.apache.causeway.viewer.graphql.model.domain.common.interactors.ActionInteractor;
+import 
org.apache.causeway.viewer.graphql.model.domain.common.query.ObjectFeatureUtils;
 
 import lombok.Getter;
 import lombok.val;
@@ -44,25 +45,25 @@ public class RichActionInvokeArgsArg
 
     public RichActionInvokeArgsArg(
             final ActionInteractor actionInteractor,
-            final ObjectActionParameter objectActionParameter,
+            final ObjectActionParameter oap,
             final Context context,
             final int paramNum) {
         super(context);
 
         this.actionInteractor = actionInteractor;
-        this.objectActionParameter = objectActionParameter;
+        this.objectActionParameter = oap;
         this.paramNum = paramNum;
 
-        val elementType = objectActionParameter.getElementType();;
+        val elementType = oap.getElementType();;
 
         val gqlObjectTypeForElementType = 
context.typeMapper.outputTypeFor(elementType, actionInteractor.getSchemaType());
         if (gqlObjectTypeForElementType != null) {
-            val gqlOutputType = objectActionParameter.isPlural()
+            val gqlOutputType = oap.isPlural()
                     ? GraphQLList.list(gqlObjectTypeForElementType)
                     : gqlObjectTypeForElementType;
 
             val fieldBuilder = newFieldDefinition()
-                    .name(objectActionParameter.getId())
+                    .name(ObjectFeatureUtils.asciiIdFor(oap))
                     .type(gqlOutputType);
             setField(fieldBuilder.build());
         } else {
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParam.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParam.java
index 347004df14..c93358ccd0 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParam.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParam.java
@@ -34,6 +34,7 @@ import 
org.apache.causeway.viewer.graphql.model.domain.SchemaType;
 import org.apache.causeway.viewer.graphql.model.domain.TypeNames;
 import 
org.apache.causeway.viewer.graphql.model.domain.common.interactors.ActionInteractor;
 import 
org.apache.causeway.viewer.graphql.model.domain.common.interactors.ActionParamInteractor;
+import 
org.apache.causeway.viewer.graphql.model.domain.common.query.ObjectFeatureUtils;
 import org.apache.causeway.viewer.graphql.model.fetcher.BookmarkedPojo;
 import 
org.apache.causeway.viewer.graphql.model.mmproviders.ObjectActionParameterProvider;
 import org.apache.causeway.viewer.graphql.model.types.TypeMapper;
@@ -100,7 +101,7 @@ public class RichActionParamsParam
         addChildFieldFor(this.validate = new 
RichActionParamsParamValidate(this, context));
         addChildFieldFor(this.datatype = new 
RichActionParamsParamDatatype(this, context));
 
-        buildObjectTypeAndField(oap.getId(), 
oap.getCanonicalDescription().orElse(oap.getCanonicalFriendlyName()));
+        buildObjectTypeAndField(ObjectFeatureUtils.asciiIdFor(oap), 
oap.getCanonicalDescription().orElse(oap.getCanonicalFriendlyName()));
     }
 
     @Override
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamAutoComplete.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamAutoComplete.java
index 58142a84f6..c9c1ef4d9d 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamAutoComplete.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamAutoComplete.java
@@ -38,7 +38,8 @@ import 
org.apache.causeway.viewer.graphql.model.context.Context;
 import org.apache.causeway.viewer.graphql.model.domain.Environment;
 import org.apache.causeway.viewer.graphql.model.domain.Element;
 import 
org.apache.causeway.viewer.graphql.model.domain.common.interactors.ActionParamInteractor;
-import org.apache.causeway.viewer.graphql.model.fetcher.BookmarkedPojo;
+ import 
org.apache.causeway.viewer.graphql.model.domain.common.query.ObjectFeatureUtils;
+ import org.apache.causeway.viewer.graphql.model.fetcher.BookmarkedPojo;
 import org.apache.causeway.viewer.graphql.model.types.TypeMapper;
 
 import lombok.val;
@@ -86,7 +87,7 @@ import lombok.extern.log4j.Log4j2;
          val objectAction = actionParamInteractor.getObjectMember();
          val managedObject = ManagedObject.adaptSingular(objectSpecification, 
sourcePojo);
 
-         val objectActionParameter = 
objectAction.getParameterById(actionParamInteractor.getObjectActionParameter().getId());
+         val objectActionParameter = 
objectAction.getParameterById(ObjectFeatureUtils.asciiIdFor(actionParamInteractor.getObjectActionParameter()));
          val argumentManagedObjects = 
actionParamInteractor.argumentManagedObjectsFor(new 
Environment.For(dataFetchingEnvironment), objectAction, 
context.bookmarkService);
 
          val managedAction = ManagedAction.of(managedObject, objectAction, 
Where.ANYWHERE);
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamChoices.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamChoices.java
index 62e7293f76..02c040ad3c 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamChoices.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamChoices.java
@@ -36,7 +36,8 @@ import 
org.apache.causeway.viewer.graphql.model.context.Context;
 import org.apache.causeway.viewer.graphql.model.domain.Environment;
 import org.apache.causeway.viewer.graphql.model.domain.Element;
 import 
org.apache.causeway.viewer.graphql.model.domain.common.interactors.ActionParamInteractor;
-import org.apache.causeway.viewer.graphql.model.fetcher.BookmarkedPojo;
+ import 
org.apache.causeway.viewer.graphql.model.domain.common.query.ObjectFeatureUtils;
+ import org.apache.causeway.viewer.graphql.model.fetcher.BookmarkedPojo;
 import org.apache.causeway.viewer.graphql.model.types.TypeMapper;
 
 import lombok.val;
@@ -78,7 +79,7 @@ import lombok.extern.log4j.Log4j2;
          val objectAction = actionParamInteractor.getObjectMember();
          val managedObject = ManagedObject.adaptSingular(objectSpecification, 
sourcePojo);
 
-         val objectActionParameter = 
objectAction.getParameterById(actionParamInteractor.getObjectActionParameter().getId());
+         val objectActionParameter = 
objectAction.getParameterById(ObjectFeatureUtils.asciiIdFor(actionParamInteractor.getObjectActionParameter()));
          val argumentManagedObjects = 
actionParamInteractor.argumentManagedObjectsFor(new 
Environment.For(dataFetchingEnvironment), objectAction, 
context.bookmarkService);
 
          val managedAction = ManagedAction.of(managedObject, objectAction, 
Where.ANYWHERE);
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamDefault.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamDefault.java
index db09480847..0c22696b1b 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamDefault.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamDefault.java
@@ -32,6 +32,7 @@ import 
org.apache.causeway.viewer.graphql.model.context.Context;
 import org.apache.causeway.viewer.graphql.model.domain.Environment;
 import org.apache.causeway.viewer.graphql.model.domain.Element;
 import 
org.apache.causeway.viewer.graphql.model.domain.common.interactors.ActionParamInteractor;
+import 
org.apache.causeway.viewer.graphql.model.domain.common.query.ObjectFeatureUtils;
 import org.apache.causeway.viewer.graphql.model.fetcher.BookmarkedPojo;
 import org.apache.causeway.viewer.graphql.model.types.TypeMapper;
 
@@ -70,7 +71,7 @@ public class RichActionParamsParamDefault extends Element {
         }
         val objectAction = actionParamInteractor.getObjectMember();
         val managedObject = ManagedObject.adaptSingular(objectSpecification, 
sourcePojo);
-        val objectActionParameter = 
objectAction.getParameterById(actionParamInteractor.getObjectActionParameter().getId());
+        val objectActionParameter = 
objectAction.getParameterById(ObjectFeatureUtils.asciiIdFor(actionParamInteractor.getObjectActionParameter()));
         val argumentManagedObjects = 
actionParamInteractor.argumentManagedObjectsFor(new 
Environment.For(dataFetchingEnvironment), objectAction, 
context.bookmarkService);
         val managedAction = ManagedAction.of(managedObject, objectAction, 
Where.ANYWHERE);
         val pendingArgs = ParameterNegotiationModel.of(managedAction, 
argumentManagedObjects);
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamDisabled.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamDisabled.java
index 1c93c82577..1e71ba9b92 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamDisabled.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamDisabled.java
@@ -29,6 +29,7 @@ import 
org.apache.causeway.viewer.graphql.model.context.Context;
 import org.apache.causeway.viewer.graphql.model.domain.Environment;
 import org.apache.causeway.viewer.graphql.model.domain.Element;
 import 
org.apache.causeway.viewer.graphql.model.domain.common.interactors.ActionParamInteractor;
+import 
org.apache.causeway.viewer.graphql.model.domain.common.query.ObjectFeatureUtils;
 import org.apache.causeway.viewer.graphql.model.fetcher.BookmarkedPojo;
 import org.apache.causeway.viewer.graphql.model.types.TypeMapper;
 
@@ -67,7 +68,7 @@ public class RichActionParamsParamDisabled extends Element {
         val managedObject = ManagedObject.adaptSingular(objectSpecification, 
sourcePojo);
         val actionInteractionHead = 
objectAction.interactionHead(managedObject);
 
-        val objectActionParameter = 
objectAction.getParameterById(actionParamInteractor.getObjectActionParameter().getId());
+        val objectActionParameter = 
objectAction.getParameterById(ObjectFeatureUtils.asciiIdFor(actionParamInteractor.getObjectActionParameter()));
         val argumentManagedObjects = 
actionParamInteractor.argumentManagedObjectsFor(new 
Environment.For(dataFetchingEnvironment), objectAction, 
context.bookmarkService);
 
         val usable = objectActionParameter.isUsable(actionInteractionHead, 
argumentManagedObjects, InteractionInitiatedBy.USER);
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamHidden.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamHidden.java
index 710f2ffbc5..c223f22a4c 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamHidden.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamHidden.java
@@ -29,7 +29,8 @@ import 
org.apache.causeway.viewer.graphql.model.context.Context;
 import org.apache.causeway.viewer.graphql.model.domain.Environment;
 import org.apache.causeway.viewer.graphql.model.domain.Element;
 import 
org.apache.causeway.viewer.graphql.model.domain.common.interactors.ActionParamInteractor;
-import org.apache.causeway.viewer.graphql.model.fetcher.BookmarkedPojo;
+ import 
org.apache.causeway.viewer.graphql.model.domain.common.query.ObjectFeatureUtils;
+ import org.apache.causeway.viewer.graphql.model.fetcher.BookmarkedPojo;
 import org.apache.causeway.viewer.graphql.model.types.TypeMapper;
 
 import lombok.val;
@@ -69,7 +70,7 @@ public class RichActionParamsParamHidden extends Element {
         val managedObject = ManagedObject.adaptSingular(objectSpecification, 
sourcePojo);
         val actionInteractionHead = 
objectAction.interactionHead(managedObject);
 
-        val objectActionParameter = 
objectAction.getParameterById(actionParamInteractor.getObjectActionParameter().getId());
+        val objectActionParameter = 
objectAction.getParameterById(ObjectFeatureUtils.asciiIdFor(actionParamInteractor.getObjectActionParameter()));
 
         val argumentManagedObjects = 
actionParamInteractor.argumentManagedObjectsFor(new 
Environment.For(dataFetchingEnvironment), objectAction, 
context.bookmarkService);
 
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamValidate.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamValidate.java
index e8e3e94ba8..8d3472d1bb 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamValidate.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionParamsParamValidate.java
@@ -29,6 +29,7 @@ import 
org.apache.causeway.viewer.graphql.model.context.Context;
 import org.apache.causeway.viewer.graphql.model.domain.Environment;
 import org.apache.causeway.viewer.graphql.model.domain.Element;
 import 
org.apache.causeway.viewer.graphql.model.domain.common.interactors.ActionParamInteractor;
+import 
org.apache.causeway.viewer.graphql.model.domain.common.query.ObjectFeatureUtils;
 import org.apache.causeway.viewer.graphql.model.fetcher.BookmarkedPojo;
 import org.apache.causeway.viewer.graphql.model.types.TypeMapper;
 
@@ -68,7 +69,7 @@ public class RichActionParamsParamValidate extends Element {
         val managedObject = ManagedObject.adaptSingular(objectSpecification, 
sourcePojo);
         val actionInteractionHead = 
objectAction.interactionHead(managedObject);
 
-        val objectActionParameter = 
objectAction.getParameterById(actionParamInteractor.getObjectActionParameter().getId());
+        val objectActionParameter = 
objectAction.getParameterById(ObjectFeatureUtils.asciiIdFor(actionParamInteractor.getObjectActionParameter()));
 
         val argumentManagedObjects = 
actionParamInteractor.argumentManagedObjectsFor(new 
Environment.For(dataFetchingEnvironment), objectAction, 
context.bookmarkService);
 
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionValidity.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionValidity.java
index 0243096c13..affbd0f5b3 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionValidity.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichActionValidity.java
@@ -34,6 +34,7 @@ import 
org.apache.causeway.core.metamodel.spec.feature.ObjectActionParameter;
 import org.apache.causeway.viewer.graphql.model.context.Context;
 import org.apache.causeway.viewer.graphql.model.domain.Element;
 import 
org.apache.causeway.viewer.graphql.model.domain.common.interactors.ActionInteractor;
+import 
org.apache.causeway.viewer.graphql.model.domain.common.query.ObjectFeatureUtils;
 import org.apache.causeway.viewer.graphql.model.fetcher.BookmarkedPojo;
 import org.apache.causeway.viewer.graphql.model.types.TypeMapper;
 
@@ -84,7 +85,7 @@ public class RichActionValidity extends Element {
         Can<ObjectActionParameter> parameters = objectAction.getParameters();
         Can<ManagedObject> argumentManagedObjects = parameters
                 .map(oap -> {
-                    Object argumentValue = argumentPojos.get(oap.getId());
+                    Object argumentValue = 
argumentPojos.get(ObjectFeatureUtils.asciiIdFor(oap));
                     return ManagedObject.adaptParameter(oap, argumentValue);
                 });
 
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichCollection.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichCollection.java
index 20b0d1b92c..ca9d0d585f 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichCollection.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichCollection.java
@@ -25,6 +25,7 @@ import 
org.apache.causeway.viewer.graphql.model.domain.SchemaType;
 import org.apache.causeway.viewer.graphql.model.domain.TypeNames;
 import 
org.apache.causeway.viewer.graphql.model.domain.common.interactors.MemberInteractor;
 import 
org.apache.causeway.viewer.graphql.model.domain.common.interactors.ObjectInteractor;
+import 
org.apache.causeway.viewer.graphql.model.domain.common.query.ObjectFeatureUtils;
 
 public class RichCollection
         extends RichAssociation<OneToManyAssociation, ObjectInteractor>
@@ -54,7 +55,7 @@ public class RichCollection
         addChildFieldFor(this.get = new RichCollectionGet(this, context));
         addChildFieldFor(this.datatype = new RichCollectionDatatype(this, 
context));
 
-        buildObjectTypeAndField(otma.getId(), 
otma.getCanonicalDescription().orElse(otma.getCanonicalFriendlyName()));
+        buildObjectTypeAndField(ObjectFeatureUtils.asciiIdFor(otma), 
otma.getCanonicalDescription().orElse(otma.getCanonicalFriendlyName()));
     }
 
     @Override
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichProperty.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichProperty.java
index c9444c22c7..0cb1ee518e 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichProperty.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichProperty.java
@@ -32,6 +32,7 @@ import 
org.apache.causeway.viewer.graphql.model.domain.TypeNames;
 import 
org.apache.causeway.viewer.graphql.model.domain.common.interactors.MemberInteractor;
 import 
org.apache.causeway.viewer.graphql.model.domain.common.interactors.ObjectInteractor;
 import 
org.apache.causeway.viewer.graphql.model.domain.common.interactors.PropertyInteractor;
+import 
org.apache.causeway.viewer.graphql.model.domain.common.query.ObjectFeatureUtils;
 import 
org.apache.causeway.viewer.graphql.model.mmproviders.ObjectMemberProvider;
 import 
org.apache.causeway.viewer.graphql.model.mmproviders.ObjectSpecificationProvider;
 import org.apache.causeway.viewer.graphql.model.mmproviders.SchemaTypeProvider;
@@ -99,7 +100,7 @@ public class RichProperty
         addChildFieldFor(this.set = isSetterAllowed() ? new 
RichPropertySet(this, context) : null);
         addChildFieldFor(this.datatype = new RichPropertyDatatype(this, 
context));
 
-        buildObjectTypeAndField(otoa.getId(), 
otoa.getCanonicalDescription().orElse(otoa.getCanonicalFriendlyName()));
+        buildObjectTypeAndField(ObjectFeatureUtils.asciiIdFor(otoa), 
otoa.getCanonicalDescription().orElse(otoa.getCanonicalFriendlyName()));
     }
 
     private boolean isSetterAllowed() {
@@ -134,11 +135,11 @@ public class RichProperty
     }
 
     private GraphQLArgument gqlArgumentFor(
-            final OneToOneAssociation oneToOneAssociation,
+            final OneToOneAssociation otoa,
             final TypeMapper.InputContext inputContext) {
         return GraphQLArgument.newArgument()
-                .name(oneToOneAssociation.getId())
-                .type(context.typeMapper.inputTypeFor(oneToOneAssociation, 
inputContext, SchemaType.RICH))
+                .name(ObjectFeatureUtils.asciiIdFor(otoa))
+                .type(context.typeMapper.inputTypeFor(otoa, inputContext, 
SchemaType.RICH))
                 .build();
     }
 
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichPropertyGetBlobBytes.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichPropertyGetBlobBytes.java
index f69bdb14dd..bcc9dfd222 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichPropertyGetBlobBytes.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichPropertyGetBlobBytes.java
@@ -23,6 +23,7 @@ import graphql.schema.DataFetchingEnvironment;
 import org.apache.causeway.core.metamodel.spec.feature.OneToOneAssociation;
 import org.apache.causeway.viewer.graphql.model.context.Context;
 import 
org.apache.causeway.viewer.graphql.model.domain.common.interactors.MemberInteractor;
+import 
org.apache.causeway.viewer.graphql.model.domain.common.query.ObjectFeatureUtils;
 import org.apache.causeway.viewer.graphql.model.fetcher.BookmarkedPojo;
 
 import lombok.val;
@@ -45,7 +46,7 @@ public class RichPropertyGetBlobBytes extends 
RichPropertyGetBlobAbstract {
 
         val bookmarkIfAny = context.bookmarkService.bookmarkFor(sourcePojo);
         return bookmarkIfAny.map(x -> String.format(
-                "//%s/object/%s:%s/%s/blobBytes", graphqlPath, 
x.getLogicalTypeName(), x.getIdentifier(), 
memberInteractor.getObjectMember().getId())).orElse(null);
+                "//%s/object/%s:%s/%s/blobBytes", graphqlPath, 
x.getLogicalTypeName(), x.getIdentifier(), 
ObjectFeatureUtils.asciiIdFor(memberInteractor.getObjectMember()))).orElse(null);
 
     }
 
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichPropertyGetClobChars.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichPropertyGetClobChars.java
index 78e2ec4a5e..c0c713ab52 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichPropertyGetClobChars.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichPropertyGetClobChars.java
@@ -23,6 +23,7 @@ import graphql.schema.DataFetchingEnvironment;
 import org.apache.causeway.core.metamodel.spec.feature.OneToOneAssociation;
 import org.apache.causeway.viewer.graphql.model.context.Context;
 import 
org.apache.causeway.viewer.graphql.model.domain.common.interactors.MemberInteractor;
+import 
org.apache.causeway.viewer.graphql.model.domain.common.query.ObjectFeatureUtils;
 import org.apache.causeway.viewer.graphql.model.fetcher.BookmarkedPojo;
 
 import lombok.val;
@@ -45,7 +46,7 @@ public class RichPropertyGetClobChars extends 
RichPropertyGetClobAbstract {
 
         val bookmarkIfAny = context.bookmarkService.bookmarkFor(sourcePojo);
         return bookmarkIfAny.map(x -> String.format(
-                "//%s/object/%s:%s/%s/clobChars", graphqlPath, 
x.getLogicalTypeName(), x.getIdentifier(), 
holder.getObjectMember().getId())).orElse(null);
+                "//%s/object/%s:%s/%s/clobChars", graphqlPath, 
x.getLogicalTypeName(), x.getIdentifier(), 
ObjectFeatureUtils.asciiIdFor(holder.getObjectMember()))).orElse(null);
 
     }
 
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichPropertySet.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichPropertySet.java
index 77f566360d..81fd99bec3 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichPropertySet.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichPropertySet.java
@@ -31,6 +31,7 @@ import 
org.apache.causeway.viewer.graphql.model.context.Context;
 import org.apache.causeway.viewer.graphql.model.domain.Element;
 import org.apache.causeway.viewer.graphql.model.domain.SchemaType;
 import 
org.apache.causeway.viewer.graphql.model.domain.common.interactors.PropertyInteractor;
+import 
org.apache.causeway.viewer.graphql.model.domain.common.query.ObjectFeatureUtils;
 import org.apache.causeway.viewer.graphql.model.exceptions.DisabledException;
 import org.apache.causeway.viewer.graphql.model.exceptions.HiddenException;
 import org.apache.causeway.viewer.graphql.model.exceptions.InvalidException;
@@ -70,29 +71,29 @@ public class RichPropertySet extends Element {
             return null;
         }
 
-        val association = propertyInteractor.getObjectMember();
+        val otoa = propertyInteractor.getObjectMember();
         val managedObject = ManagedObject.adaptSingular(objectSpecification, 
sourcePojo);
 
         Map<String, Object> arguments = dataFetchingEnvironment.getArguments();
-        Object argumentValue = arguments.get(association.getId());
-        ManagedObject argumentManagedObject = 
ManagedObject.adaptProperty(association, argumentValue);
+        Object argumentValue = 
arguments.get(ObjectFeatureUtils.asciiIdFor(otoa));
+        ManagedObject argumentManagedObject = 
ManagedObject.adaptProperty(otoa, argumentValue);
 
-        val visibleConsent = association.isVisible(managedObject, 
InteractionInitiatedBy.USER, Where.ANYWHERE);
+        val visibleConsent = otoa.isVisible(managedObject, 
InteractionInitiatedBy.USER, Where.ANYWHERE);
         if (visibleConsent.isVetoed()) {
-            throw new HiddenException(association.getFeatureIdentifier());
+            throw new HiddenException(otoa.getFeatureIdentifier());
         }
 
-        val usableConsent = association.isUsable(managedObject, 
InteractionInitiatedBy.USER, Where.ANYWHERE);
+        val usableConsent = otoa.isUsable(managedObject, 
InteractionInitiatedBy.USER, Where.ANYWHERE);
         if (usableConsent.isVetoed()) {
-            throw new DisabledException(association.getFeatureIdentifier());
+            throw new DisabledException(otoa.getFeatureIdentifier());
         }
 
-        val validityConsent = association.isAssociationValid(managedObject, 
argumentManagedObject, InteractionInitiatedBy.USER);
+        val validityConsent = otoa.isAssociationValid(managedObject, 
argumentManagedObject, InteractionInitiatedBy.USER);
         if (validityConsent.isVetoed()) {
             throw new InvalidException(validityConsent);
         }
 
-        association.set(managedObject, argumentManagedObject, 
InteractionInitiatedBy.USER);
+        otoa.set(managedObject, argumentManagedObject, 
InteractionInitiatedBy.USER);
 
         return managedObject; // return the original object because setters 
return void
     }
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichPropertyValidate.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichPropertyValidate.java
index 9ddf075b3c..021c15fcac 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichPropertyValidate.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/rich/query/RichPropertyValidate.java
@@ -28,6 +28,7 @@ import 
org.apache.causeway.core.metamodel.object.ManagedObject;
 import org.apache.causeway.viewer.graphql.model.context.Context;
 import org.apache.causeway.viewer.graphql.model.domain.Element;
 import 
org.apache.causeway.viewer.graphql.model.domain.common.interactors.PropertyInteractor;
+import 
org.apache.causeway.viewer.graphql.model.domain.common.query.ObjectFeatureUtils;
 import org.apache.causeway.viewer.graphql.model.fetcher.BookmarkedPojo;
 import org.apache.causeway.viewer.graphql.model.types.TypeMapper;
 
@@ -61,14 +62,14 @@ public class RichPropertyValidate extends Element {
             return null;
         }
 
-        val association = holder.getObjectMember();
+        val otoa = holder.getObjectMember();
         val managedObject = ManagedObject.adaptSingular(objectSpecification, 
sourcePojo);
 
         val arguments = dataFetchingEnvironment.getArguments();
-        val argumentValue = arguments.get(association.getId());
-        val argumentManagedObject = ManagedObject.adaptProperty(association, 
argumentValue);
+        val argumentValue = arguments.get(ObjectFeatureUtils.asciiIdFor(otoa));
+        val argumentManagedObject = ManagedObject.adaptProperty(otoa, 
argumentValue);
 
-        val valid = association.isAssociationValid(managedObject, 
argumentManagedObject, InteractionInitiatedBy.USER);
+        val valid = otoa.isAssociationValid(managedObject, 
argumentManagedObject, InteractionInitiatedBy.USER);
         return valid.isVetoed() ? valid.getReasonAsString().orElse("invalid") 
: null;
     }
 
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/mutation/SimpleMutationForAction.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/mutation/SimpleMutationForAction.java
index a5e6758b5c..e8151680cf 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/mutation/SimpleMutationForAction.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/mutation/SimpleMutationForAction.java
@@ -49,7 +49,7 @@ import 
org.apache.causeway.viewer.graphql.model.domain.Environment;
 import org.apache.causeway.viewer.graphql.model.domain.Element;
 import org.apache.causeway.viewer.graphql.model.domain.SchemaType;
 import org.apache.causeway.viewer.graphql.model.domain.TypeNames;
-import 
org.apache.causeway.viewer.graphql.model.domain.common.query.CommonActionUtils;
+import 
org.apache.causeway.viewer.graphql.model.domain.common.query.ObjectFeatureUtils;
 import org.apache.causeway.viewer.graphql.model.exceptions.DisabledException;
 import org.apache.causeway.viewer.graphql.model.exceptions.HiddenException;
 import org.apache.causeway.viewer.graphql.model.fetcher.BookmarkedPojo;
@@ -91,8 +91,8 @@ public class SimpleMutationForAction extends Element {
 
     private static String fieldName(
             final ObjectSpecification objectSpecification,
-            final ObjectAction objectAction) {
-        return TypeNames.objectTypeFieldNameFor(objectSpecification) + "__" + 
objectAction.getId();
+            final ObjectAction oa) {
+        return TypeNames.objectTypeFieldNameFor(objectSpecification) + "__" + 
ObjectFeatureUtils.asciiIdFor(oa);
     }
 
     @Nullable
@@ -156,7 +156,7 @@ public class SimpleMutationForAction extends Element {
             } else {
                 val refValue = (String)argumentValue.get("ref");
                 if (refValue != null) {
-                    val key = CommonActionUtils.keyFor(refValue);
+                    val key = ObjectFeatureUtils.keyFor(refValue);
                     BookmarkedPojo value = ((Environment) 
environment).getGraphQlContext().get(key);
                     result = 
Optional.of(value).map(BookmarkedPojo::getTargetPojo);
                 } else {
@@ -226,25 +226,25 @@ public class SimpleMutationForAction extends Element {
     }
 
     // adapted from SimpleAction
-    GraphQLArgument gqlArgumentFor(final OneToOneActionParameter 
oneToOneActionParameter) {
+    GraphQLArgument gqlArgumentFor(final OneToOneActionParameter otoap) {
         return GraphQLArgument.newArgument()
-                .name(oneToOneActionParameter.getId())
-                .type(context.typeMapper.inputTypeFor(oneToOneActionParameter, 
TypeMapper.InputContext.INVOKE, SchemaType.RICH))
+                .name(ObjectFeatureUtils.asciiIdFor(otoap))
+                .type(context.typeMapper.inputTypeFor(otoap, 
TypeMapper.InputContext.INVOKE, SchemaType.RICH))
                 .build();
     }
 
     // adapted from SimpleAction
-    GraphQLArgument gqlArgumentFor(final OneToManyActionParameter 
oneToManyActionParameter) {
+    GraphQLArgument gqlArgumentFor(final OneToManyActionParameter otmap) {
         return GraphQLArgument.newArgument()
-                .name(oneToManyActionParameter.getId())
-                
.type(context.typeMapper.inputTypeFor(oneToManyActionParameter, 
SchemaType.RICH))
+                .name(ObjectFeatureUtils.asciiIdFor(otmap))
+                .type(context.typeMapper.inputTypeFor(otmap, SchemaType.RICH))
                 .build();
     }
 
     private Can<ManagedObject> argumentManagedObjectsFor(
             final Environment dataFetchingEnvironment,
             final ObjectAction objectAction) {
-        return 
CommonActionUtils.argumentManagedObjectsFor(dataFetchingEnvironment, 
objectAction, context);
+        return 
ObjectFeatureUtils.argumentManagedObjectsFor(dataFetchingEnvironment, 
objectAction, context);
     }
 
 
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/mutation/SimpleMutationForProperty.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/mutation/SimpleMutationForProperty.java
index 4550ba1fa5..0074ce1bd5 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/mutation/SimpleMutationForProperty.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/mutation/SimpleMutationForProperty.java
@@ -39,7 +39,7 @@ import 
org.apache.causeway.viewer.graphql.model.domain.Environment;
 import org.apache.causeway.viewer.graphql.model.domain.Element;
 import org.apache.causeway.viewer.graphql.model.domain.SchemaType;
 import org.apache.causeway.viewer.graphql.model.domain.TypeNames;
-import 
org.apache.causeway.viewer.graphql.model.domain.common.query.CommonActionUtils;
+import 
org.apache.causeway.viewer.graphql.model.domain.common.query.ObjectFeatureUtils;
 import org.apache.causeway.viewer.graphql.model.exceptions.DisabledException;
 import org.apache.causeway.viewer.graphql.model.exceptions.HiddenException;
 import org.apache.causeway.viewer.graphql.model.exceptions.InvalidException;
@@ -81,8 +81,8 @@ public class SimpleMutationForProperty extends Element {
 
     private static String fieldName(
             final ObjectSpecification objectSpecification,
-            final OneToOneAssociation oneToOneAssociation) {
-        return TypeNames.objectTypeFieldNameFor(objectSpecification) + "__" + 
oneToOneAssociation.getId();
+            final OneToOneAssociation otoa) {
+        return TypeNames.objectTypeFieldNameFor(objectSpecification) + "__" + 
ObjectFeatureUtils.asciiIdFor(otoa);
     }
 
     @Override
@@ -110,7 +110,7 @@ public class SimpleMutationForProperty extends Element {
         } else {
             val refValue = (String)argumentValue1.get("ref");
             if (refValue != null) {
-                String key = CommonActionUtils.keyFor(refValue);
+                String key = ObjectFeatureUtils.keyFor(refValue);
                 BookmarkedPojo value = 
environment.getGraphQlContext().get(key);
                 result = Optional.of(value).map(BookmarkedPojo::getTargetPojo);
             } else {
@@ -123,7 +123,7 @@ public class SimpleMutationForProperty extends Element {
         val managedObject = ManagedObject.adaptSingular(objectSpec, 
sourcePojo);
 
         Map<String, Object> arguments = dataFetchingEnvironment.getArguments();
-        Object argumentValue = arguments.get(oneToOneAssociation.getId());
+        Object argumentValue = 
arguments.get(ObjectFeatureUtils.asciiIdFor(oneToOneAssociation));
         ManagedObject argumentManagedObject = 
ManagedObject.adaptProperty(oneToOneAssociation, argumentValue);
 
         val visibleConsent = oneToOneAssociation.isVisible(managedObject, 
InteractionInitiatedBy.USER, Where.ANYWHERE);
@@ -160,7 +160,7 @@ public class SimpleMutationForProperty extends Element {
 
         fieldBuilder.argument(
                 GraphQLArgument.newArgument()
-                        .name(oneToOneAssociation.getId())
+                        
.name(ObjectFeatureUtils.asciiIdFor(oneToOneAssociation))
                         
.type(context.typeMapper.inputTypeFor(oneToOneAssociation, 
TypeMapper.InputContext.INVOKE, SchemaType.RICH))
                         .build());
     }
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/SimpleAction.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/SimpleAction.java
index 19b426d0b5..ed65e8c24f 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/SimpleAction.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/SimpleAction.java
@@ -48,7 +48,7 @@ import 
org.apache.causeway.viewer.graphql.model.context.Context;
 import org.apache.causeway.viewer.graphql.model.domain.Environment;
 import org.apache.causeway.viewer.graphql.model.domain.Element;
 import 
org.apache.causeway.viewer.graphql.model.domain.common.interactors.ObjectInteractor;
-import 
org.apache.causeway.viewer.graphql.model.domain.common.query.CommonActionUtils;
+import 
org.apache.causeway.viewer.graphql.model.domain.common.query.ObjectFeatureUtils;
 import org.apache.causeway.viewer.graphql.model.exceptions.DisabledException;
 import org.apache.causeway.viewer.graphql.model.exceptions.HiddenException;
 import org.apache.causeway.viewer.graphql.model.fetcher.BookmarkedPojo;
@@ -86,7 +86,7 @@ public class SimpleAction
     }
 
     public String getId() {
-        return objectMember.getId();
+        return ObjectFeatureUtils.asciiIdFor(objectMember);
     }
 
     private GraphQLOutputType typeFor(final ObjectAction objectAction){
@@ -143,7 +143,7 @@ public class SimpleAction
         return parameters
                 .map(oap -> {
                     final ObjectSpecification elementType = 
oap.getElementType();
-                    Object argumentValue = argumentPojos.get(oap.getId());
+                    Object argumentValue = 
argumentPojos.get(ObjectFeatureUtils.asciiIdFor(oap));
                     Object pojoOrPojoList;
 
                     switch (elementType.getBeanSort()) {
@@ -211,7 +211,7 @@ public class SimpleAction
 
         val refValue = (String)argumentValue.get("ref");
         if (refValue != null) {
-            String key = CommonActionUtils.keyFor(refValue);
+            String key = ObjectFeatureUtils.keyFor(refValue);
             BookmarkedPojo bookmarkedPojo = 
environment.getGraphQlContext().get(key);
             if (bookmarkedPojo == null) {
                 throw new IllegalArgumentException(String.format(
@@ -276,25 +276,23 @@ public class SimpleAction
             final ObjectActionParameter objectActionParameter,
             final TypeMapper.InputContext inputContext) {
         return objectActionParameter.isPlural()
-                ? gqlArgumentFor((OneToManyActionParameter) 
objectActionParameter, inputContext)
+                ? gqlArgumentFor((OneToManyActionParameter) 
objectActionParameter)
                 : gqlArgumentFor((OneToOneActionParameter) 
objectActionParameter, inputContext);
     }
 
     GraphQLArgument gqlArgumentFor(
-            final OneToOneActionParameter oneToOneActionParameter,
+            final OneToOneActionParameter otoap,
             final TypeMapper.InputContext inputContext) {
         return GraphQLArgument.newArgument()
-                .name(oneToOneActionParameter.getId())
-                .type(context.typeMapper.inputTypeFor(oneToOneActionParameter, 
inputContext, objectInteractor.getSchemaType()))
+                .name(ObjectFeatureUtils.asciiIdFor(otoap))
+                .type(context.typeMapper.inputTypeFor(otoap, inputContext, 
objectInteractor.getSchemaType()))
                 .build();
     }
 
-    GraphQLArgument gqlArgumentFor(
-            final OneToManyActionParameter oneToManyActionParameter,
-            final TypeMapper.InputContext inputContext) {
+    GraphQLArgument gqlArgumentFor(final OneToManyActionParameter otmap) {
         return GraphQLArgument.newArgument()
-                .name(oneToManyActionParameter.getId())
-                
.type(context.typeMapper.inputTypeFor(oneToManyActionParameter, 
objectInteractor.getSchemaType()))
+                .name(ObjectFeatureUtils.asciiIdFor(otmap))
+                .type(context.typeMapper.inputTypeFor(otmap, 
objectInteractor.getSchemaType()))
                 .build();
     }
 
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/SimpleCollection.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/SimpleCollection.java
index 6801164935..941e91aaa2 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/SimpleCollection.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/SimpleCollection.java
@@ -27,6 +27,7 @@ import 
org.apache.causeway.core.metamodel.spec.feature.OneToManyAssociation;
 import org.apache.causeway.viewer.graphql.model.context.Context;
 import org.apache.causeway.viewer.graphql.model.domain.Element;
 import 
org.apache.causeway.viewer.graphql.model.domain.common.interactors.ObjectInteractor;
+import 
org.apache.causeway.viewer.graphql.model.domain.common.query.ObjectFeatureUtils;
 import org.apache.causeway.viewer.graphql.model.fetcher.BookmarkedPojo;
 
 import lombok.val;
@@ -60,7 +61,7 @@ public class SimpleCollection
     }
 
     public String getId() {
-        return objectMember.getId();
+        return ObjectFeatureUtils.asciiIdFor(objectMember);
     }
 
     @Override
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/SimpleProperty.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/SimpleProperty.java
index 58d0628f90..7661daec07 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/SimpleProperty.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/SimpleProperty.java
@@ -39,6 +39,7 @@ import 
org.apache.causeway.viewer.graphql.model.domain.SchemaType;
 import org.apache.causeway.viewer.graphql.model.domain.TypeNames;
 import 
org.apache.causeway.viewer.graphql.model.domain.common.interactors.MemberInteractor;
 import 
org.apache.causeway.viewer.graphql.model.domain.common.interactors.ObjectInteractor;
+import 
org.apache.causeway.viewer.graphql.model.domain.common.query.ObjectFeatureUtils;
 import org.apache.causeway.viewer.graphql.model.fetcher.BookmarkedPojo;
 
 import lombok.Getter;
@@ -103,7 +104,7 @@ public class SimpleProperty
 
         if (gqlOutputType != null) {
             val fieldBuilder = newFieldDefinition()
-                    .name(otoa.getId())
+                    .name(ObjectFeatureUtils.asciiIdFor(otoa))
                     .type(gqlOutputType);
             setField(fieldBuilder.build());
         } else {
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/SimplePropertyLobBytes.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/SimplePropertyLobBytes.java
index df62dba8a0..a0cc7ec016 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/SimplePropertyLobBytes.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/SimplePropertyLobBytes.java
@@ -23,6 +23,7 @@ import graphql.schema.DataFetchingEnvironment;
 import org.apache.causeway.core.metamodel.spec.feature.OneToOneAssociation;
 import org.apache.causeway.viewer.graphql.model.context.Context;
 import 
org.apache.causeway.viewer.graphql.model.domain.common.interactors.MemberInteractor;
+import 
org.apache.causeway.viewer.graphql.model.domain.common.query.ObjectFeatureUtils;
 import org.apache.causeway.viewer.graphql.model.fetcher.BookmarkedPojo;
 
 import lombok.val;
@@ -45,7 +46,7 @@ public class SimplePropertyLobBytes extends 
SimplePropertyLobAbstract {
 
         val bookmarkIfAny = context.bookmarkService.bookmarkFor(sourcePojo);
         return bookmarkIfAny.map(x -> String.format(
-                "//%s/object/%s:%s/%s/blobBytes", graphqlPath, 
x.getLogicalTypeName(), x.getIdentifier(), 
memberInteractor.getObjectMember().getId())).orElse(null);
+                "//%s/object/%s:%s/%s/blobBytes", graphqlPath, 
x.getLogicalTypeName(), x.getIdentifier(), 
ObjectFeatureUtils.asciiIdFor(memberInteractor.getObjectMember()))).orElse(null);
 
     }
 
diff --git 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/SimplePropertyLobChars.java
 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/SimplePropertyLobChars.java
index b4e529a34b..be7473b58f 100644
--- 
a/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/SimplePropertyLobChars.java
+++ 
b/viewers/graphql/model/src/main/java/org/apache/causeway/viewer/graphql/model/domain/simple/query/SimplePropertyLobChars.java
@@ -23,6 +23,7 @@ import graphql.schema.DataFetchingEnvironment;
 import org.apache.causeway.core.metamodel.spec.feature.OneToOneAssociation;
 import org.apache.causeway.viewer.graphql.model.context.Context;
 import 
org.apache.causeway.viewer.graphql.model.domain.common.interactors.MemberInteractor;
+import 
org.apache.causeway.viewer.graphql.model.domain.common.query.ObjectFeatureUtils;
 import org.apache.causeway.viewer.graphql.model.fetcher.BookmarkedPojo;
 
 import lombok.val;
@@ -45,7 +46,7 @@ public class SimplePropertyLobChars extends 
SimplePropertyLobAbstract {
 
         val bookmarkIfAny = context.bookmarkService.bookmarkFor(sourcePojo);
         return bookmarkIfAny.map(x -> String.format(
-                "//%s/object/%s:%s/%s/clobChars", graphqlPath, 
x.getLogicalTypeName(), x.getIdentifier(), 
memberInteractor.getObjectMember().getId())).orElse(null);
+                "//%s/object/%s:%s/%s/clobChars", graphqlPath, 
x.getLogicalTypeName(), x.getIdentifier(), 
ObjectFeatureUtils.asciiIdFor(memberInteractor.getObjectMember()))).orElse(null);
 
     }
 

Reply via email to