You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@causeway.apache.org by da...@apache.org on 2023/03/27 08:33:59 UTC

[causeway] branch master updated (d0ade5ee3e -> 39bdbce250)

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

danhaywood pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/causeway.git


    from d0ade5ee3e CAUSEWAY-3400: discontinue incubator projects (docs)
     new bd151649b3 CAUSEWAY-2485 : @DomainObject#autoComplete
     new 39bdbce250 CAUSEWAY-2485: polishes DomainObject#aliased, DomainObject#autoComplete...

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../src/main/java/demoapp/dom/DemoModuleJpa.java   |  6 ++-
 .../{Customer.java => DomainObjectAliased.java}    |  8 +---
 ...r.layout.xml => DomainObjectAliased.layout.xml} |  0
 ...ies.java => DomainObjectAliasedRepository.java} | 20 +++------
 ...eeding.java => DomainObjectAliasedSeeding.java} |  6 +--
 .../aliased/DomainObjectAliasedVm-description.adoc | 13 ++++--
 .../aliased/DomainObjectAliasedVm.java             |  2 +-
 .../aliased/DomainObjectAliasedVm.layout.xml       |  3 +-
 .../aliased/DomainObjectAliasedVm_lookup.java      | 22 +++++++---
 ...kup.java => DomainObjectAliasedVm_objects.java} | 13 +++---
 .../aliased/DomainObjectAliasedVm_people.java      | 38 ----------------
 ...doc => DomainObjectAliasedJpa-description.adoc} |  2 +-
 ...ustomerJpa.java => DomainObjectAliasedJpa.java} | 12 +++---
 ...es.java => DomainObjectAliasedJpaEntities.java} | 20 ++++++---
 .../autoComplete/DomainObjectAutoComplete.java}    | 24 +++++------
 .../DomainObjectAutoComplete.layout.xml}           |  0
 .../DomainObjectAutoCompleteRepository.java        | 21 ++++++++-
 .../DomainObjectAutoCompleteSeeding.java}          | 13 +++---
 .../DomainObjectAutoCompleteVm-description.adoc    | 28 ++++++++----
 .../autoComplete/DomainObjectAutoCompleteVm.java   |  9 ----
 .../DomainObjectAutoCompleteVm.layout.xml          |  3 ++
 .../DomainObjectAutoCompleteVm_find.java           | 24 +++++++++++
 .../DomainObjectAutoCompleteVm_objects.java        | 31 ++++++++++++++
 .../DomainObjectAutoCompleteJpa-description.adoc   | 50 +++++++---------------
 .../jpa/DomainObjectAutoCompleteJpa.java}          | 16 ++++---
 .../jpa/DomainObjectAutoCompleteJpaEntities.java}  | 19 ++++----
 ...ObjectEntityChangePublishingVm-description.adoc |  2 +-
 .../demoapp/dom/homepage/DemoHomePage-welcome.adoc |  4 +-
 28 files changed, 224 insertions(+), 185 deletions(-)
 rename examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/{Customer.java => DomainObjectAliased.java} (87%)
 copy examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/{Customer.layout.xml => DomainObjectAliased.layout.xml} (100%)
 copy examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/{jpa/CustomerJpaEntities.java => DomainObjectAliasedRepository.java} (72%)
 rename examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/{CustomerSeeding.java => DomainObjectAliasedSeeding.java} (87%)
 copy examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/{DomainObjectAliasedVm_lookup.java => DomainObjectAliasedVm_objects.java} (55%)
 delete mode 100644 examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedVm_people.java
 rename examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/{CustomerJpa-description.adoc => DomainObjectAliasedJpa-description.adoc} (94%)
 copy examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/{CustomerJpa.java => DomainObjectAliasedJpa.java} (82%)
 rename examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/{CustomerJpaEntities.java => DomainObjectAliasedJpaEntities.java} (62%)
 copy examples/demo/domain/src/main/java/demoapp/dom/domain/{properties/Property/projecting/persistence/PropertyProjectingChildEntity.java => objects/DomainObject/autoComplete/DomainObjectAutoComplete.java} (70%)
 rename examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/{aliased/Customer.layout.xml => autoComplete/DomainObjectAutoComplete.layout.xml} (100%)
 copy examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/{nature/viewmodels/jaxbrefentity/JaxbRefSeeding.java => autoComplete/DomainObjectAutoCompleteSeeding.java} (82%)
 create mode 100644 examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoCompleteVm_find.java
 create mode 100644 examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoCompleteVm_objects.java
 copy antora/components/refguide-index/modules/applib/pages/index/services/wrapper/control/ExecutionMode.adoc => examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/jpa/DomainObjectAutoCompleteJpa-description.adoc (54%)
 rename examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/{aliased/jpa/CustomerJpa.java => autoComplete/jpa/DomainObjectAutoCompleteJpa.java} (71%)
 copy examples/demo/domain/src/main/java/demoapp/dom/{types/javalang/strings/jpa/JavaLangStringJpaEntities.java => domain/objects/DomainObject/autoComplete/jpa/DomainObjectAutoCompleteJpaEntities.java} (71%)


[causeway] 02/02: CAUSEWAY-2485: polishes DomainObject#aliased, DomainObject#autoComplete...

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 39bdbce2504b713a7f5515811ea10e5f256e38e6
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Mon Mar 27 09:32:16 2023 +0100

    CAUSEWAY-2485: polishes DomainObject#aliased, DomainObject#autoComplete...
---
 ...ities.java => DomainObjectAliasedRepository.java} | 20 ++++++--------------
 .../aliased/DomainObjectAliasedVm-description.adoc   |  5 +++--
 .../aliased/DomainObjectAliasedVm_lookup.java        | 15 +++++++++++++++
 .../aliased/jpa/DomainObjectAliasedJpaEntities.java  | 10 +++++++++-
 .../DomainObjectAutoCompleteVm-description.adoc      |  8 +++++---
 .../demoapp/dom/homepage/DemoHomePage-welcome.adoc   |  4 ++--
 6 files changed, 40 insertions(+), 22 deletions(-)

diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/DomainObjectAliasedJpaEntities.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedRepository.java
similarity index 69%
copy from examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/DomainObjectAliasedJpaEntities.java
copy to examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedRepository.java
index be6c05735b..5f02c80287 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/DomainObjectAliasedJpaEntities.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedRepository.java
@@ -16,25 +16,17 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package demoapp.dom.domain.objects.DomainObject.aliased.jpa;
+package demoapp.dom.domain.objects.DomainObject.aliased;
 
 import demoapp.dom._infra.values.ValueHolderRepository;
+import demoapp.dom.domain.objects.DomainObject.aliased.jpa.DomainObjectAliasedJpa;
+
+import java.util.List;
 
 import org.springframework.context.annotation.Profile;
 import org.springframework.stereotype.Service;
 
-@Profile("demo-jpa")
-@Service
-public class DomainObjectAliasedJpaEntities
-extends ValueHolderRepository<String, DomainObjectAliasedJpa> {
-
-    protected DomainObjectAliasedJpaEntities() {
-        super(DomainObjectAliasedJpa.class);
-    }
-
-    @Override
-    protected DomainObjectAliasedJpa newDetachedEntity(String value) {
-        return new DomainObjectAliasedJpa(value);
-    }
+public interface DomainObjectAliasedRepository {
 
+    List<? extends DomainObjectAliased> allInstances();
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedVm-description.adoc b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedVm-description.adoc
index 68b16e09ea..003a3ad349 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedVm-description.adoc
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedVm-description.adoc
@@ -16,9 +16,10 @@ However, any bookmarks in the old format of "customer.Customer:1234" should stil
 
 === How this demo works
 
-The collection on the left shows a set of `Customer` entity instances, each indicating their current bookmark and a previous bookmark that corresponds to the value of their link:https://causeway.apache.org/refguide/2.0.0-SNAPSHOT/applib/index/annotation/DomainObject.html#aliased[@DomainObject#alias].
+The collection on the left shows a set of entity instances, each indicating their current bookmark and a previous bookmark that corresponds to the value of their link:https://causeway.apache.org/refguide/2.0.0-SNAPSHOT/applib/index/annotation/DomainObject.html#aliased[@DomainObject#alias].
 
-The "lookup" (mixin) action allows any of these objects to be shown using either bookmark:
+The "lookup" (mixin) action uses the https://causeway.apache.org/refguide/2.0.0-SNAPSHOT/applib/index/services/bookmark/BookmarkService.html[BookmarkService] to lookup any object using either their current bookmark (defined by `@Named`) or their previous bookmark (defined by `@DomainObject#alias`).
+For convenience, the action provides a choices method for all possible values.
 
 [source,java,indent=0]
 ----
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedVm_lookup.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedVm_lookup.java
index 2c65abc4af..46b865d35c 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedVm_lookup.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedVm_lookup.java
@@ -1,12 +1,17 @@
 package demoapp.dom.domain.objects.DomainObject.aliased;
 
 import lombok.RequiredArgsConstructor;
+import lombok.val;
+
+import java.util.ArrayList;
+import java.util.List;
 
 import javax.inject.Inject;
 
 import org.apache.causeway.applib.annotation.*;
 import org.apache.causeway.applib.services.bookmark.Bookmark;
 import org.apache.causeway.applib.services.bookmark.BookmarkService;
+import org.apache.causeway.applib.services.repository.RepositoryService;
 
 //tag::class[]
 @Action(semantics = SemanticsOf.SAFE)
@@ -20,7 +25,17 @@ public class DomainObjectAliasedVm_lookup {
     public DomainObjectAliased act(final String bookmark) {
         return bookmarkService.lookup(Bookmark.parseElseFail(bookmark), DomainObjectAliased.class).orElseThrow(() -> new org.apache.causeway.applib.exceptions.RecoverableException("No customer exists for that bookmark"));
     }
+    public List<String> choices0Act() {
+        val bookmarks = new ArrayList<String>();
+        val aliases = repository.allInstances();
+        aliases.stream().forEach(obj -> {
+            bookmarks.add(obj.getBookmark());
+            bookmarks.add(obj.getPreviousBookmark());
+        });
+        return bookmarks;
+    }
 
+    @Inject DomainObjectAliasedRepository repository;
     @Inject BookmarkService bookmarkService;
 }
 //end::class[]
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/DomainObjectAliasedJpaEntities.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/DomainObjectAliasedJpaEntities.java
index be6c05735b..cd3f92d90e 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/DomainObjectAliasedJpaEntities.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/DomainObjectAliasedJpaEntities.java
@@ -19,6 +19,10 @@
 package demoapp.dom.domain.objects.DomainObject.aliased.jpa;
 
 import demoapp.dom._infra.values.ValueHolderRepository;
+import demoapp.dom.domain.objects.DomainObject.aliased.DomainObjectAliased;
+import demoapp.dom.domain.objects.DomainObject.aliased.DomainObjectAliasedRepository;
+
+import java.util.List;
 
 import org.springframework.context.annotation.Profile;
 import org.springframework.stereotype.Service;
@@ -26,7 +30,7 @@ import org.springframework.stereotype.Service;
 @Profile("demo-jpa")
 @Service
 public class DomainObjectAliasedJpaEntities
-extends ValueHolderRepository<String, DomainObjectAliasedJpa> {
+extends ValueHolderRepository<String, DomainObjectAliasedJpa> implements DomainObjectAliasedRepository {
 
     protected DomainObjectAliasedJpaEntities() {
         super(DomainObjectAliasedJpa.class);
@@ -37,4 +41,8 @@ extends ValueHolderRepository<String, DomainObjectAliasedJpa> {
         return new DomainObjectAliasedJpa(value);
     }
 
+    @Override
+    public List<? extends DomainObjectAliased> allInstances() {
+        return all();
+    }
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoCompleteVm-description.adoc b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoCompleteVm-description.adoc
index 214487e598..b44e2a81d1 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoCompleteVm-description.adoc
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoCompleteVm-description.adoc
@@ -11,15 +11,17 @@ TIP: In fact, the return type of the `autoComplete` method does not need to exac
 
 === How this demo works
 
-The collection on the left shows a set of `Customer` entity instances.
+The collection on the left shows a set of entity instances, of type `DomainObjectAutoComplete`.
 
-The "find" (mixin) action defines a `Customer` as its parameter type, and simply returns it.
+The "find" (mixin) action defines the entity class as its parameter type, and simply returns it.
 
 [source,java,indent=0]
 ----
 include::DomainObjectAutoCompleteVm_find.java[tags=class]
 ----
 
-The autoComplete search is specified in the `Customer` type itself, using the link:https://causeway.apache.org/refguide/2.0.0-SNAPSHOT/applib/index/annotation/DomainObject.html#autoCompleteRepository[autoCompleteRepository] and link:https://causeway.apache.org/refguide/2.0.0-SNAPSHOT/applib/index/annotation/DomainObject.html#autoCompleteMethod[autoCompleteMethod] attributes.
+<.> xxx
+
+The autoComplete search to perform is specified using the link:https://causeway.apache.org/refguide/2.0.0-SNAPSHOT/applib/index/annotation/DomainObject.html#autoCompleteRepository[autoCompleteRepository] and link:https://causeway.apache.org/refguide/2.0.0-SNAPSHOT/applib/index/annotation/DomainObject.html#autoCompleteMethod[autoCompleteMethod] attributes.
 
 Navigate through to the entity to see the corresponding source code.
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/homepage/DemoHomePage-welcome.adoc b/examples/demo/domain/src/main/java/demoapp/dom/homepage/DemoHomePage-welcome.adoc
index 04c9d0562b..372e776627 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/homepage/DemoHomePage-welcome.adoc
+++ b/examples/demo/domain/src/main/java/demoapp/dom/homepage/DemoHomePage-welcome.adoc
@@ -4,7 +4,7 @@ This is an link:https://causeway.apache.org[Apache Causeway] application to demo
 
 On the left hand side of each web page you'll find the feature, and on the right hand side you'll find an explanation of the feature with code examples.
 
-== Page Layout
+=== Page Layout
 
 This is as good place as any to explain the page layout of an Apache Causeway webapp:
 
@@ -31,7 +31,7 @@ Click into the application and try things out.
 The demo app uses an in-memory database, so any changes made will be lost when the app is stopped.
 ====
 
-== Getting Help and Assistance
+=== Getting Help and Assistance
 
 There is plenty of documentation on our link:https://causeway.apache.org/docs/${CAUSEWAY_VERSION}/about.html[website].
 Also subscribe to our link:https://causeway.apache.org/docs/${CAUSEWAY_VERSION}/support/mailing-list.html[mailing list] or join our link:https://causeway.apache.org/docs/${CAUSEWAY_VERSION}/support/slack-channel.html[Slack channel].


[causeway] 01/02: CAUSEWAY-2485 : @DomainObject#autoComplete

Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit bd151649b3be9afab8d4e3d0c6b3b8bd70201e6f
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Sun Mar 26 12:52:51 2023 +0100

    CAUSEWAY-2485 : @DomainObject#autoComplete
---
 .../src/main/java/demoapp/dom/DemoModuleJpa.java   |  6 ++--
 .../{Customer.java => DomainObjectAliased.java}    |  8 +----
 ...r.layout.xml => DomainObjectAliased.layout.xml} |  0
 ...eeding.java => DomainObjectAliasedSeeding.java} |  6 ++--
 .../aliased/DomainObjectAliasedVm-description.adoc | 10 ++++--
 .../aliased/DomainObjectAliasedVm.java             |  2 +-
 .../aliased/DomainObjectAliasedVm.layout.xml       |  3 +-
 .../aliased/DomainObjectAliasedVm_lookup.java      | 11 +++----
 ...kup.java => DomainObjectAliasedVm_objects.java} | 13 ++++----
 .../aliased/DomainObjectAliasedVm_people.java      | 38 ----------------------
 ...doc => DomainObjectAliasedJpa-description.adoc} |  2 +-
 ...ustomerJpa.java => DomainObjectAliasedJpa.java} | 12 +++----
 ...es.java => DomainObjectAliasedJpaEntities.java} | 12 +++----
 ...pository.java => DomainObjectAutoComplete.java} | 23 ++++++++++---
 .../DomainObjectAutoComplete.layout.xml}           |  0
 .../DomainObjectAutoCompleteRepository.java        | 21 +++++++++++-
 .../DomainObjectAutoCompleteSeeding.java}          |  8 ++---
 .../DomainObjectAutoCompleteVm-description.adoc    | 26 ++++++++++-----
 .../autoComplete/DomainObjectAutoCompleteVm.java   |  9 -----
 .../DomainObjectAutoCompleteVm.layout.xml          |  3 ++
 .../DomainObjectAutoCompleteVm_find.java           | 24 ++++++++++++++
 .../DomainObjectAutoCompleteVm_objects.java        | 31 ++++++++++++++++++
 .../DomainObjectAutoCompleteJpa-description.adoc}  | 18 ++++++++--
 .../jpa/DomainObjectAutoCompleteJpa.java}          | 16 +++++----
 .../jpa/DomainObjectAutoCompleteJpaEntities.java}  | 14 ++++----
 ...ObjectEntityChangePublishingVm-description.adoc |  2 +-
 26 files changed, 193 insertions(+), 125 deletions(-)

diff --git a/examples/demo/domain/src/main/java/demoapp/dom/DemoModuleJpa.java b/examples/demo/domain/src/main/java/demoapp/dom/DemoModuleJpa.java
index 7e40b962b6..86afd966fe 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/DemoModuleJpa.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/DemoModuleJpa.java
@@ -28,7 +28,8 @@ import org.apache.causeway.persistence.jpa.eclipselink.CausewayModulePersistence
 
 import demoapp.dom.domain.actions.Action.commandPublishing.jpa.ActionCommandPublishingJpa;
 import demoapp.dom.domain.actions.Action.executionPublishing.jpa.ActionExecutionPublishingJpa;
-import demoapp.dom.domain.objects.DomainObject.aliased.jpa.CustomerJpa;
+import demoapp.dom.domain.objects.DomainObject.aliased.jpa.DomainObjectAliasedJpa;
+import demoapp.dom.domain.objects.DomainObject.autoComplete.jpa.DomainObjectAutoCompleteJpa;
 import demoapp.dom.domain.objects.DomainObject.entityChangePublishing.annotated.disabled.jpa.DomainObjectEntityChangePublishingDisabledJpa;
 import demoapp.dom.domain.objects.DomainObject.entityChangePublishing.annotated.enabled.jpa.DomainObjectEntityChangePublishingEnabledJpa;
 import demoapp.dom.domain.objects.DomainObject.entityChangePublishing.metaAnnot.enabled.jpa.DomainObjectEntityChangePublishingEnabledMetaAnnotatedJpa;
@@ -92,7 +93,8 @@ import demoapp.dom.types.primitive.shorts.jpa.PrimitiveShortJpa;
 })
 @EntityScan(basePackageClasses = {
 
-        CustomerJpa.class,
+        DomainObjectAliasedJpa.class,
+        DomainObjectAutoCompleteJpa.class,
 
         CausewayBlobJpa.class,
         CausewayClobJpa.class,
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/Customer.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliased.java
similarity index 87%
rename from examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/Customer.java
rename to examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliased.java
index 9e22a3bc68..8bb9ba6bea 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/Customer.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliased.java
@@ -19,20 +19,14 @@
 package demoapp.dom.domain.objects.DomainObject.aliased;
 
 import javax.inject.Inject;
-import javax.inject.Named;
 
-import org.apache.causeway.applib.annotation.DomainObject;
 import org.apache.causeway.applib.annotation.Property;
 import org.apache.causeway.applib.services.bookmark.BookmarkService;
 
 import demoapp.dom._infra.asciidocdesc.HasAsciiDocDescription;
 import demoapp.dom._infra.values.ValueHolder;
 
-@Named("demo.party.Customer")                   // <.>
-@DomainObject(
-        aliased = {"demo.customer.Customer"}    // <.>
-)
-public abstract class Customer
+public abstract class DomainObjectAliased
         implements
         HasAsciiDocDescription,
         ValueHolder<String> {
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/Customer.layout.xml b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliased.layout.xml
similarity index 100%
copy from examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/Customer.layout.xml
copy to examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliased.layout.xml
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/CustomerSeeding.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedSeeding.java
similarity index 87%
copy from examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/CustomerSeeding.java
copy to examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedSeeding.java
index fd9d5b8263..67c12db3ab 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/CustomerSeeding.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedSeeding.java
@@ -26,12 +26,12 @@ import javax.inject.Inject;
 import org.springframework.stereotype.Service;
 
 @Service
-public class CustomerSeeding
+public class DomainObjectAliasedSeeding
 extends SeedServiceAbstract {
 
     @Inject
-    public CustomerSeeding(
-            ValueHolderRepository<String, ? extends Customer> entities) {
+    public DomainObjectAliasedSeeding(
+            ValueHolderRepository<String, ? extends DomainObjectAliased> entities) {
         super(entities);
     }
 
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedVm-description.adoc b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedVm-description.adoc
index dab44df916..68b16e09ea 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedVm-description.adoc
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedVm-description.adoc
@@ -14,10 +14,16 @@ For example, suppose an `Customer` type initially is part of the "customer" modu
 Later on, you decide to move `Customer` to a more generic "party" module, with a new logical type name being "party.Customer".
 However, any bookmarks in the old format of "customer.Customer:1234" should still resolve.
 
-=== Explanation of this Demo
+=== How this demo works
 
 The collection on the left shows a set of `Customer` entity instances, each indicating their current bookmark and a previous bookmark that corresponds to the value of their link:https://causeway.apache.org/refguide/2.0.0-SNAPSHOT/applib/index/annotation/DomainObject.html#aliased[@DomainObject#alias].
 
-The "lookup" action allows any of these objects to be shown using either bookmark.
+The "lookup" (mixin) action allows any of these objects to be shown using either bookmark:
 
+[source,java,indent=0]
+----
+include::DomainObjectAliasedVm_lookup.java[tags=class]
+----
+
+Navigate through to the entity to see the corresponding source code.
 
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedVm.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedVm.java
index 4a618d0080..4f91d34b08 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedVm.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedVm.java
@@ -29,7 +29,6 @@ import org.apache.causeway.applib.annotation.ObjectSupport;
 
 import demoapp.dom._infra.asciidocdesc.HasAsciiDocDescription;
 
-//tag::class[]
 @XmlRootElement(name = "root")
 @XmlType
 @XmlAccessorType(XmlAccessType.FIELD)
@@ -43,4 +42,5 @@ public class DomainObjectAliasedVm implements HasAsciiDocDescription {
     }
 
 }
+//tag::class[]
 //end::class[]
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedVm.layout.xml b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedVm.layout.xml
index d857ab5602..6475b00890 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedVm.layout.xml
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedVm.layout.xml
@@ -27,7 +27,7 @@
 	<bs3:row>
 		<bs3:col span="6">
 			<cpt:fieldSet name="Other" id="other" unreferencedProperties="true"/>
-			<cpt:collection id="people">
+			<cpt:collection id="objects">
 				<cpt:action id="lookup"/>
 			</cpt:collection>
 		</bs3:col>
@@ -39,6 +39,7 @@
 				<cpt:action id="downloadMetamodelXml"  position="PANEL_DROPDOWN"/>
 				<cpt:action id="inspectMetamodel"  position="PANEL_DROPDOWN"/>
                 <cpt:action id="recentCommands"  position="PANEL_DROPDOWN"/>
+				<cpt:action id="downloadJdoMetadata"  position="PANEL_DROPDOWN"/>
 				<cpt:action id="openRestApi" position="PANEL_DROPDOWN" />
 				<cpt:property id="description"/>
 			</cpt:fieldSet>
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedVm_lookup.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedVm_lookup.java
index 686635f08b..2c65abc4af 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedVm_lookup.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedVm_lookup.java
@@ -1,18 +1,15 @@
 package demoapp.dom.domain.objects.DomainObject.aliased;
 
-import demoapp.dom._infra.values.ValueHolderRepository;
 import lombok.RequiredArgsConstructor;
 
-import java.util.List;
-
 import javax.inject.Inject;
 
 import org.apache.causeway.applib.annotation.*;
 import org.apache.causeway.applib.services.bookmark.Bookmark;
 import org.apache.causeway.applib.services.bookmark.BookmarkService;
 
+//tag::class[]
 @Action(semantics = SemanticsOf.SAFE)
-@ActionLayout(associateWith = "people")
 @RequiredArgsConstructor
 public class DomainObjectAliasedVm_lookup {
 
@@ -20,10 +17,10 @@ public class DomainObjectAliasedVm_lookup {
     private final DomainObjectAliasedVm mixee;
 
     @MemberSupport
-    public Customer act(final String bookmark) {
-        return bookmarkService.lookup(Bookmark.parseElseFail(bookmark), Customer.class).orElseThrow(() -> new org.apache.causeway.applib.exceptions.RecoverableException("No customer exists for that bookmark"));
+    public DomainObjectAliased act(final String bookmark) {
+        return bookmarkService.lookup(Bookmark.parseElseFail(bookmark), DomainObjectAliased.class).orElseThrow(() -> new org.apache.causeway.applib.exceptions.RecoverableException("No customer exists for that bookmark"));
     }
 
     @Inject BookmarkService bookmarkService;
-
 }
+//end::class[]
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedVm_lookup.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedVm_objects.java
similarity index 55%
copy from examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedVm_lookup.java
copy to examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedVm_objects.java
index 686635f08b..b766d34704 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedVm_lookup.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedVm_objects.java
@@ -11,19 +11,20 @@ import org.apache.causeway.applib.annotation.*;
 import org.apache.causeway.applib.services.bookmark.Bookmark;
 import org.apache.causeway.applib.services.bookmark.BookmarkService;
 
-@Action(semantics = SemanticsOf.SAFE)
-@ActionLayout(associateWith = "people")
+@Collection()
+@CollectionLayout()
 @RequiredArgsConstructor
-public class DomainObjectAliasedVm_lookup {
+public class DomainObjectAliasedVm_objects {
 
     @SuppressWarnings("unused")
     private final DomainObjectAliasedVm mixee;
 
     @MemberSupport
-    public Customer act(final String bookmark) {
-        return bookmarkService.lookup(Bookmark.parseElseFail(bookmark), Customer.class).orElseThrow(() -> new org.apache.causeway.applib.exceptions.RecoverableException("No customer exists for that bookmark"));
+    public List<? extends DomainObjectAliased> coll() {
+        return objectRepository.all();
     }
 
-    @Inject BookmarkService bookmarkService;
+    @Inject
+    ValueHolderRepository<String, ? extends DomainObjectAliased> objectRepository;
 
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedVm_people.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedVm_people.java
deleted file mode 100644
index 1a52e21416..0000000000
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/DomainObjectAliasedVm_people.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package demoapp.dom.domain.objects.DomainObject.aliased;
-
-import demoapp.dom._infra.values.ValueHolderRepository;
-import lombok.RequiredArgsConstructor;
-
-import java.util.List;
-import java.util.Optional;
-
-import javax.inject.Inject;
-
-import org.apache.causeway.applib.annotation.*;
-import org.apache.causeway.applib.services.bookmark.Bookmark;
-import org.apache.causeway.applib.services.bookmark.BookmarkService;
-
-@Collection()
-@CollectionLayout()
-@RequiredArgsConstructor
-public class DomainObjectAliasedVm_people {
-
-    @SuppressWarnings("unused")
-    private final DomainObjectAliasedVm mixee;
-
-    @MemberSupport
-    public List<? extends Customer> coll() {
-        return addressEntities.all();
-    }
-
-    @Inject
-    ValueHolderRepository<String, ? extends Customer> addressEntities;
-
-    @Action(semantics = SemanticsOf.SAFE)
-    public Customer lookup(final String bookmark) {
-        return bookmarkService.lookup(Bookmark.parseElseFail(bookmark), Customer.class).orElseThrow(() -> new org.apache.causeway.applib.exceptions.RecoverableException("No customer exists for that bookmark"));
-    }
-
-    @Inject BookmarkService bookmarkService;
-
-}
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/CustomerJpa-description.adoc b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/DomainObjectAliasedJpa-description.adoc
similarity index 94%
copy from examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/CustomerJpa-description.adoc
copy to examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/DomainObjectAliasedJpa-description.adoc
index 995fb2eddd..4f54c95f54 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/CustomerJpa-description.adoc
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/DomainObjectAliasedJpa-description.adoc
@@ -2,7 +2,7 @@
 
 [source,java,indent=0]
 ----
-include::CustomerJpa.java[tags=class]
+include::DomainObjectAliasedJpa.java[tags=class]
 ----
 <.> current logical type name
 <.> previous logical type names
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/CustomerJpa.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/DomainObjectAliasedJpa.java
similarity index 82%
copy from examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/CustomerJpa.java
copy to examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/DomainObjectAliasedJpa.java
index 690617e51a..a91cd1b835 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/CustomerJpa.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/DomainObjectAliasedJpa.java
@@ -18,7 +18,7 @@
  */
 package demoapp.dom.domain.objects.DomainObject.aliased.jpa;
 
-import demoapp.dom.domain.objects.DomainObject.aliased.Customer;
+import demoapp.dom.domain.objects.DomainObject.aliased.DomainObjectAliased;
 import lombok.Getter;
 import lombok.NoArgsConstructor;
 import lombok.Setter;
@@ -35,19 +35,19 @@ import org.springframework.context.annotation.Profile;
 @Entity
 @Table(
     schema = "demo",
-    name = "AddressJpa"
+    name = "DomainObjectAliasedJpa"
 )
 @EntityListeners(CausewayEntityListener.class)
-@Named("demo.address.Address")                  // <.>
+@Named("demo.party.Customer")                   // <.>
 @DomainObject(
-    aliased = {"demo.customer.Address"}         // <.>
+        aliased = {"demo.customer.Customer"}    // <.>
 )
 @NoArgsConstructor
-public class CustomerJpa extends Customer {
+public class DomainObjectAliasedJpa extends DomainObjectAliased {
     // ...
 //end::class[]
 
-    public CustomerJpa(String value) {
+    public DomainObjectAliasedJpa(String value) {
         setName(value);
     }
 
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/CustomerJpaEntities.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/DomainObjectAliasedJpaEntities.java
similarity index 77%
copy from examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/CustomerJpaEntities.java
copy to examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/DomainObjectAliasedJpaEntities.java
index 7cc4663f34..be6c05735b 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/CustomerJpaEntities.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/DomainObjectAliasedJpaEntities.java
@@ -25,16 +25,16 @@ import org.springframework.stereotype.Service;
 
 @Profile("demo-jpa")
 @Service
-public class CustomerJpaEntities
-extends ValueHolderRepository<String, CustomerJpa> {
+public class DomainObjectAliasedJpaEntities
+extends ValueHolderRepository<String, DomainObjectAliasedJpa> {
 
-    protected CustomerJpaEntities() {
-        super(CustomerJpa.class);
+    protected DomainObjectAliasedJpaEntities() {
+        super(DomainObjectAliasedJpa.class);
     }
 
     @Override
-    protected CustomerJpa newDetachedEntity(String value) {
-        return new CustomerJpa(value);
+    protected DomainObjectAliasedJpa newDetachedEntity(String value) {
+        return new DomainObjectAliasedJpa(value);
     }
 
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoCompleteRepository.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoComplete.java
similarity index 63%
copy from examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoCompleteRepository.java
copy to examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoComplete.java
index 56fd3a182e..ce4578123a 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoCompleteRepository.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoComplete.java
@@ -18,12 +18,25 @@
  */
 package demoapp.dom.domain.objects.DomainObject.autoComplete;
 
-import org.springframework.stereotype.Repository;
+import demoapp.dom._infra.asciidocdesc.HasAsciiDocDescription;
+import demoapp.dom._infra.values.ValueHolder;
 
-//tag::class[]
-@Repository
-public class DomainObjectAutoCompleteRepository {
+@SuppressWarnings("CdiManagedBeanInconsistencyInspection")
+public abstract class DomainObjectAutoComplete
+        implements
+        HasAsciiDocDescription,
+        ValueHolder<String> {
 
+    public String title() {
+        return value();
+    }
+
+    @Override
+    public String value() {
+        return getName();
+    }
+
+    public abstract String getName();
+    public abstract void setName(String value);
 
 }
-//end::class[]
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/Customer.layout.xml b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoComplete.layout.xml
similarity index 100%
rename from examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/Customer.layout.xml
rename to examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoComplete.layout.xml
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoCompleteRepository.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoCompleteRepository.java
index 56fd3a182e..1a5c4aa966 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoCompleteRepository.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoCompleteRepository.java
@@ -18,12 +18,31 @@
  */
 package demoapp.dom.domain.objects.DomainObject.autoComplete;
 
+import java.util.List;
+import java.util.stream.Collectors;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.apache.causeway.applib.annotation.MinLength;
+import org.apache.causeway.applib.services.repository.RepositoryService;
 import org.springframework.stereotype.Repository;
 
+@Named("demo.DomainObjectAutoCompleteRepository")
 //tag::class[]
 @Repository
-public class DomainObjectAutoCompleteRepository {
+public class DomainObjectAutoCompleteRepository {                               // <.>
 
+    public List<DomainObjectAutoComplete> findMatching(                         // <.>
+                @MinLength(1)                                                   // <.>
+                final String search
+    ) {
+        return repositoryService.allInstances(DomainObjectAutoComplete.class)   // <.>
+                .stream()
+                .filter(x -> x.getName().contains(search))
+                .collect(Collectors.toList());
+    }
 
+    @Inject private RepositoryService repositoryService;
 }
 //end::class[]
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/CustomerSeeding.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoCompleteSeeding.java
similarity index 82%
rename from examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/CustomerSeeding.java
rename to examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoCompleteSeeding.java
index fd9d5b8263..1570db9ae2 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/CustomerSeeding.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoCompleteSeeding.java
@@ -16,7 +16,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package demoapp.dom.domain.objects.DomainObject.aliased;
+package demoapp.dom.domain.objects.DomainObject.autoComplete;
 
 import demoapp.dom._infra.seed.SeedServiceAbstract;
 import demoapp.dom._infra.values.ValueHolderRepository;
@@ -26,12 +26,12 @@ import javax.inject.Inject;
 import org.springframework.stereotype.Service;
 
 @Service
-public class CustomerSeeding
+public class DomainObjectAutoCompleteSeeding
 extends SeedServiceAbstract {
 
     @Inject
-    public CustomerSeeding(
-            ValueHolderRepository<String, ? extends Customer> entities) {
+    public DomainObjectAutoCompleteSeeding(
+            ValueHolderRepository<String, ? extends DomainObjectAutoComplete> entities) {
         super(entities);
     }
 
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoCompleteVm-description.adoc b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoCompleteVm-description.adoc
index 779a4308f8..214487e598 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoCompleteVm-description.adoc
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoCompleteVm-description.adoc
@@ -1,15 +1,25 @@
 :Notice: 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 ag [...]
 
-The `autoCompleteRepository` attribute ...
+If an action parameter is a reference type (typically an entity), then a mechanism is required to present a list of relevant existing instances for the end-user to select.
+One means to do that is to write a supporting `choices` or `autoComplete` method for the action; `choices` if there is a comparatively short list, or `autoComplete` if the list of candidates if long: the end-user enters some characters and these are used to search for available instances that are relevant for this particular action.
 
-WARNING: TODO[CAUSEWAY-3312]
-The class of the domain service that provides an autoComplete(String) method.
-It is sufficient to specify an interface rather than a concrete type.
+If the list of available instances is always or often the same, then this can result in a lot of boilerplate.
+The link:https://causeway.apache.org/refguide/2.0.0-SNAPSHOT/applib/index/annotation/DomainObject.html#autoCompleteRepository[@DomainObject#autoCompleteRepository] attribute allows a `@Repository` service to be nominated as containing a suitable `autoComplete(String)` method returning a list of the corresponding domain class.
+The link:https://causeway.apache.org/refguide/2.0.0-SNAPSHOT/applib/index/annotation/DomainObject.html#autoCompleteMethod[@DomainObject#autoCompleteMethod] attribute can be used if the name of this method is something other than the default of "autoComplete".
 
-The `autoCompleteMethod` attribute ...
+TIP: In fact, the return type of the `autoComplete` method does not need to exactly match that of the annotated domain type; it is sufficient to return any superclass or indeed an interface.
 
-WARNING: TODO[CAUSEWAY-3312]
-The method to use in order to perform the auto-complete search (defaults to "autoComplete").
-The method is required to accept a single string parameter, and must return a list of the domain type.
+=== How this demo works
 
+The collection on the left shows a set of `Customer` entity instances.
 
+The "find" (mixin) action defines a `Customer` as its parameter type, and simply returns it.
+
+[source,java,indent=0]
+----
+include::DomainObjectAutoCompleteVm_find.java[tags=class]
+----
+
+The autoComplete search is specified in the `Customer` type itself, using the link:https://causeway.apache.org/refguide/2.0.0-SNAPSHOT/applib/index/annotation/DomainObject.html#autoCompleteRepository[autoCompleteRepository] and link:https://causeway.apache.org/refguide/2.0.0-SNAPSHOT/applib/index/annotation/DomainObject.html#autoCompleteMethod[autoCompleteMethod] attributes.
+
+Navigate through to the entity to see the corresponding source code.
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoCompleteVm.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoCompleteVm.java
index 151d22d9e0..d40af75365 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoCompleteVm.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoCompleteVm.java
@@ -30,7 +30,6 @@ import org.apache.causeway.applib.annotation.ObjectSupport;
 
 import demoapp.dom._infra.asciidocdesc.HasAsciiDocDescription;
 
-//tag::class[]
 @XmlRootElement(name = "root")
 @XmlType
 @XmlAccessorType(XmlAccessType.FIELD)
@@ -43,12 +42,4 @@ public class DomainObjectAutoCompleteVm implements HasAsciiDocDescription {
         return "DomainObject#autoComplete...";
     }
 
-    /*
-     * TODO on an entity ...
-    @DomainObject(
-        autoCompleteRepository = DomainObjectAutoCompleteRepository.class,
-        autoCompleteMethod = "myAutoComplete")
-    */
-
 }
-//end::class[]
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoCompleteVm.layout.xml b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoCompleteVm.layout.xml
index b4f853de75..18ecaf7b16 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoCompleteVm.layout.xml
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoCompleteVm.layout.xml
@@ -27,6 +27,9 @@
 	<bs3:row>
 		<bs3:col span="6">
 			<cpt:fieldSet name="Other" id="other" unreferencedProperties="true"/>
+			<cpt:collection id="objects">
+				<cpt:action id="find"/>
+			</cpt:collection>
 		</bs3:col>
 		<bs3:col span="6">
 			<cpt:fieldSet name="Description" id="description" >
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoCompleteVm_find.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoCompleteVm_find.java
new file mode 100644
index 0000000000..cb934a5f35
--- /dev/null
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoCompleteVm_find.java
@@ -0,0 +1,24 @@
+package demoapp.dom.domain.objects.DomainObject.autoComplete;
+
+import demoapp.dom.domain.objects.DomainObject.aliased.DomainObjectAliased;
+import lombok.RequiredArgsConstructor;
+
+import org.apache.causeway.applib.annotation.Action;
+import org.apache.causeway.applib.annotation.MemberSupport;
+import org.apache.causeway.applib.annotation.SemanticsOf;
+
+//tag::class[]
+@Action(semantics = SemanticsOf.SAFE)
+@RequiredArgsConstructor
+public class DomainObjectAutoCompleteVm_find {
+
+    @SuppressWarnings("unused")
+    private final DomainObjectAutoCompleteVm mixee;
+
+    @MemberSupport
+    public DomainObjectAliased act(final DomainObjectAliased domainObjectAliased) {  // <.>
+        return domainObjectAliased;
+    }
+
+}
+//end::class[]
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoCompleteVm_objects.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoCompleteVm_objects.java
new file mode 100644
index 0000000000..4095c373f1
--- /dev/null
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/DomainObjectAutoCompleteVm_objects.java
@@ -0,0 +1,31 @@
+package demoapp.dom.domain.objects.DomainObject.autoComplete;
+
+import demoapp.dom._infra.values.ValueHolderRepository;
+import demoapp.dom.domain.objects.DomainObject.aliased.DomainObjectAliased;
+import lombok.RequiredArgsConstructor;
+
+import java.util.List;
+
+import javax.inject.Inject;
+
+import org.apache.causeway.applib.annotation.*;
+import org.apache.causeway.applib.services.bookmark.Bookmark;
+import org.apache.causeway.applib.services.bookmark.BookmarkService;
+
+@Collection()
+@CollectionLayout()
+@RequiredArgsConstructor
+public class DomainObjectAutoCompleteVm_objects {
+
+    @SuppressWarnings("unused")
+    private final DomainObjectAutoCompleteVm mixee;
+
+    @MemberSupport
+    public List<? extends DomainObjectAutoComplete> coll() {
+        return objectRepository.all();
+    }
+
+    @Inject
+    ValueHolderRepository<String, ? extends DomainObjectAutoComplete> objectRepository;
+
+}
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/CustomerJpa-description.adoc b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/jpa/DomainObjectAutoCompleteJpa-description.adoc
similarity index 53%
rename from examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/CustomerJpa-description.adoc
rename to examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/jpa/DomainObjectAutoCompleteJpa-description.adoc
index 995fb2eddd..2789e83ba8 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/CustomerJpa-description.adoc
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/jpa/DomainObjectAutoCompleteJpa-description.adoc
@@ -1,8 +1,20 @@
 :Notice: 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 ag [...]
 
 [source,java,indent=0]
+.DomainObjectAutoCompleteJpa.java
 ----
-include::CustomerJpa.java[tags=class]
+include::DomainObjectAutoCompleteJpa.java[tags=class]
 ----
-<.> current logical type name
-<.> previous logical type names
+<.> indicates the autocomplete repository
+<.> indicates to use a method called "findMatching"
+
+[source,java,indent=0]
+.DomainObjectAutoCompleteRepository.java
+----
+include::../DomainObjectAutoCompleteRepository.java[tags=class]
+----
+<.> as specified in `@DomainObject#autoCompleteRepository`
+<.> as specified the `@DomainObject#autoCompleteMethod`
+<.> specifies the minimum number of characters required to be entered before a search is triggered.
+<.> This is a naive implementation using client-side filtering.
+In a real-world app we would most likely use a JPAQL query for a server-side search
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/CustomerJpa.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/jpa/DomainObjectAutoCompleteJpa.java
similarity index 71%
rename from examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/CustomerJpa.java
rename to examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/jpa/DomainObjectAutoCompleteJpa.java
index 690617e51a..3680f28df1 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/CustomerJpa.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/jpa/DomainObjectAutoCompleteJpa.java
@@ -16,9 +16,10 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package demoapp.dom.domain.objects.DomainObject.aliased.jpa;
+package demoapp.dom.domain.objects.DomainObject.autoComplete.jpa;
 
-import demoapp.dom.domain.objects.DomainObject.aliased.Customer;
+import demoapp.dom.domain.objects.DomainObject.autoComplete.DomainObjectAutoComplete;
+import demoapp.dom.domain.objects.DomainObject.autoComplete.DomainObjectAutoCompleteRepository;
 import lombok.Getter;
 import lombok.NoArgsConstructor;
 import lombok.Setter;
@@ -35,19 +36,20 @@ import org.springframework.context.annotation.Profile;
 @Entity
 @Table(
     schema = "demo",
-    name = "AddressJpa"
+    name = "DomainObjectAutoCompleteCustomerJpa"
 )
 @EntityListeners(CausewayEntityListener.class)
-@Named("demo.address.Address")                  // <.>
+@Named("demo.autoComplete.Customer")
 @DomainObject(
-    aliased = {"demo.customer.Address"}         // <.>
+        autoCompleteRepository = DomainObjectAutoCompleteRepository.class,  // <.>
+        autoCompleteMethod = "findMatching"                 // <.>
 )
 @NoArgsConstructor
-public class CustomerJpa extends Customer {
+public class DomainObjectAutoCompleteJpa extends DomainObjectAutoComplete {
     // ...
 //end::class[]
 
-    public CustomerJpa(String value) {
+    public DomainObjectAutoCompleteJpa(String value) {
         setName(value);
     }
 
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/CustomerJpaEntities.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/jpa/DomainObjectAutoCompleteJpaEntities.java
similarity index 71%
rename from examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/CustomerJpaEntities.java
rename to examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/jpa/DomainObjectAutoCompleteJpaEntities.java
index 7cc4663f34..66096b3fce 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/aliased/jpa/CustomerJpaEntities.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/autoComplete/jpa/DomainObjectAutoCompleteJpaEntities.java
@@ -16,7 +16,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package demoapp.dom.domain.objects.DomainObject.aliased.jpa;
+package demoapp.dom.domain.objects.DomainObject.autoComplete.jpa;
 
 import demoapp.dom._infra.values.ValueHolderRepository;
 
@@ -25,16 +25,16 @@ import org.springframework.stereotype.Service;
 
 @Profile("demo-jpa")
 @Service
-public class CustomerJpaEntities
-extends ValueHolderRepository<String, CustomerJpa> {
+public class DomainObjectAutoCompleteJpaEntities
+extends ValueHolderRepository<String, DomainObjectAutoCompleteJpa> {
 
-    protected CustomerJpaEntities() {
-        super(CustomerJpa.class);
+    protected DomainObjectAutoCompleteJpaEntities() {
+        super(DomainObjectAutoCompleteJpa.class);
     }
 
     @Override
-    protected CustomerJpa newDetachedEntity(String value) {
-        return new CustomerJpa(value);
+    protected DomainObjectAutoCompleteJpa newDetachedEntity(String value) {
+        return new DomainObjectAutoCompleteJpa(value);
     }
 
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/entityChangePublishing/DomainObjectEntityChangePublishingVm-description.adoc b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/entityChangePublishing/DomainObjectEntityChangePublishingVm-description.adoc
index 26d3624260..a5db42ced6 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/entityChangePublishing/DomainObjectEntityChangePublishingVm-description.adoc
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/entityChangePublishing/DomainObjectEntityChangePublishingVm-description.adoc
@@ -14,7 +14,7 @@ The element can be specified using either the `@DomainObject` annotation, or thr
 NOTE: Publishing of domain objects is only supported for domain entities, not view models.
 
 
-== Explanation of the Demo
+=== How this demo works
 
 This current page is a view model which has four collections of entities, each a different annotations: