You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2021/05/20 07:42:23 UTC

[isis] branch master updated: ISIS-2620: Demo: create wrapper value entities for JPA

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

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


The following commit(s) were added to refs/heads/master by this push:
     new c9021ed  ISIS-2620: Demo: create wrapper value entities for JPA
c9021ed is described below

commit c9021ed0e8fa081cf0d22a4aef2df64518364ba3
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu May 20 09:42:12 2021 +0200

    ISIS-2620: Demo: create wrapper value entities for JPA
---
 .../src/main/java/demoapp/dom/DemoModuleJpa.java   | 22 +++++
 .../types/javalang/booleans/WrapperBooleans.java   | 14 ++--
 .../jpa/WrapperBooleanJpa-description.adoc         | 24 ++++++
 .../javalang/booleans/jpa/WrapperBooleanJpa.java   | 95 ++++++++++++++++++++++
 .../booleans/jpa/WrapperBooleanJpaEntities.java}   | 27 +++---
 .../dom/types/javalang/bytes/WrapperBytes.java     | 12 ++-
 .../bytes/jpa/WrapperByteJpa-description.adoc      | 23 ++++++
 .../types/javalang/bytes/jpa/WrapperByteJpa.java   | 95 ++++++++++++++++++++++
 .../bytes/jpa/WrapperByteJpaEntities.java}         | 27 +++---
 .../javalang/characters/WrapperCharacters.java     | 12 ++-
 .../jpa/WrapperCharacterJpa-description.adoc       | 23 ++++++
 .../characters/jpa/WrapperCharacterJpa.java        | 95 ++++++++++++++++++++++
 .../jpa/WrapperCharacterJpaEntities.java}          | 27 +++---
 .../dom/types/javalang/doubles/WrapperDoubles.java | 12 ++-
 .../doubles/jpa/WrapperDoubleJpa-description.adoc  | 23 ++++++
 .../javalang/doubles/jpa/WrapperDoubleJpa.java     | 95 ++++++++++++++++++++++
 .../doubles/jpa/WrapperDoubleJpaEntities.java}     | 27 +++---
 .../dom/types/javalang/floats/WrapperFloats.java   | 12 ++-
 .../floats/jpa/WrapperFloatJpa-description.adoc    | 23 ++++++
 .../types/javalang/floats/jpa/WrapperFloatJpa.java | 95 ++++++++++++++++++++++
 .../floats/jpa/WrapperFloatJpaEntities.java}       | 29 ++++---
 .../types/javalang/integers/WrapperIntegers.java   | 12 ++-
 .../jpa/WrapperIntegerJpa-description.adoc         | 23 ++++++
 .../javalang/integers/jpa/WrapperIntegerJpa.java   | 95 ++++++++++++++++++++++
 .../integers/jpa/WrapperIntegerJpaEntities.java}   | 27 +++---
 .../dom/types/javalang/longs/WrapperLongs.java     | 12 ++-
 .../longs/jpa/WrapperLongJpa-description.adoc      | 24 ++++++
 .../types/javalang/longs/jpa/WrapperLongJpa.java   | 95 ++++++++++++++++++++++
 .../longs/jpa/WrapperLongJpaEntities.java}         | 27 +++---
 .../dom/types/javalang/shorts/WrapperShorts.java   | 12 ++-
 .../shorts/jpa/WrapperShortJpa-description.adoc    | 23 ++++++
 .../types/javalang/shorts/jpa/WrapperShortJpa.java | 95 ++++++++++++++++++++++
 .../shorts/jpa/WrapperShortJpaEntities.java}       | 27 +++---
 .../main/java/demoapp/web/DemoAppManifestJpa.java  |  5 --
 34 files changed, 1130 insertions(+), 159 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 f2a9c94..8667168 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/DemoModuleJpa.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/DemoModuleJpa.java
@@ -18,6 +18,7 @@
  */
 package demoapp.dom;
 
+import org.springframework.boot.autoconfigure.domain.EntityScan;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Import;
 import org.springframework.context.annotation.Profile;
@@ -25,6 +26,16 @@ import org.springframework.context.annotation.Profile;
 import org.apache.isis.extensions.commandlog.jpa.IsisModuleExtCommandLogJpa;
 import org.apache.isis.persistence.jpa.eclipselink.IsisModuleJpaEclipselink;
 
+import demoapp.dom.types.javalang.booleans.jpa.WrapperBooleanJpa;
+import demoapp.dom.types.javalang.bytes.jpa.WrapperByteJpa;
+import demoapp.dom.types.javalang.characters.jpa.WrapperCharacterJpa;
+import demoapp.dom.types.javalang.doubles.jpa.WrapperDoubleJpa;
+import demoapp.dom.types.javalang.floats.jpa.WrapperFloatJpa;
+import demoapp.dom.types.javalang.integers.jpa.WrapperIntegerJpa;
+import demoapp.dom.types.javalang.longs.jpa.WrapperLongJpa;
+import demoapp.dom.types.javalang.shorts.jpa.WrapperShortJpa;
+import demoapp.dom.types.javalang.strings.jpa.JavaLangStringJpa;
+
 @Configuration
 @Profile("demo-jpa")
 @Import({
@@ -32,6 +43,17 @@ import org.apache.isis.persistence.jpa.eclipselink.IsisModuleJpaEclipselink;
     IsisModuleJpaEclipselink.class,
     IsisModuleExtCommandLogJpa.class,
 })
+@EntityScan(basePackageClasses = {
+        JavaLangStringJpa.class,
+        WrapperBooleanJpa.class,
+        WrapperDoubleJpa.class,
+        WrapperFloatJpa.class,
+        WrapperCharacterJpa.class,
+        WrapperLongJpa.class,
+        WrapperIntegerJpa.class,
+        WrapperShortJpa.class,
+        WrapperByteJpa.class,
+})
 public class DemoModuleJpa {
 
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/booleans/WrapperBooleans.java b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/booleans/WrapperBooleans.java
index 4381f3b..5841e91 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/booleans/WrapperBooleans.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/booleans/WrapperBooleans.java
@@ -29,26 +29,24 @@ import javax.xml.bind.annotation.XmlType;
 
 import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.ActionLayout;
-import org.apache.isis.applib.annotation.MemberSupport;
 import org.apache.isis.applib.annotation.Collection;
 import org.apache.isis.applib.annotation.DomainObject;
 import org.apache.isis.applib.annotation.Editing;
+import org.apache.isis.applib.annotation.MemberSupport;
 import org.apache.isis.applib.annotation.Nature;
 import org.apache.isis.applib.annotation.PromptStyle;
 import org.apache.isis.applib.annotation.SemanticsOf;
 
-import lombok.extern.log4j.Log4j2;
-
 import demoapp.dom._infra.asciidocdesc.HasAsciiDocDescription;
-import demoapp.dom.types.javalang.booleans.jdo.WrapperBooleanJdo;
-import demoapp.dom.types.javalang.booleans.jdo.WrapperBooleanJdoEntities;
+import demoapp.dom._infra.values.ValueHolderRepository;
+import demoapp.dom.types.javalang.booleans.persistence.WrapperBooleanEntity;
 import demoapp.dom.types.javalang.booleans.vm.WrapperBooleanVm;
 
 @XmlRootElement(name = "Demo")
 @XmlType
 @XmlAccessorType(XmlAccessType.FIELD)
 @DomainObject(nature=Nature.VIEW_MODEL, objectType = "demo.WrapperBooleans", editing=Editing.ENABLED)
-@Log4j2
+//@Log4j2
 public class WrapperBooleans implements HasAsciiDocDescription {
 
     public String title() {
@@ -65,13 +63,13 @@ public class WrapperBooleans implements HasAsciiDocDescription {
     }
 
     @Collection
-    public List<WrapperBooleanJdo> getEntities() {
+    public List<? extends WrapperBooleanEntity> getEntities() {
         return entities.all();
     }
 
     @Inject
     @XmlTransient
-    WrapperBooleanJdoEntities entities;
+    ValueHolderRepository<Boolean, ? extends WrapperBooleanEntity> entities;
 
 
     //FIXME[ISIS-2387]
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/booleans/jpa/WrapperBooleanJpa-description.adoc b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/booleans/jpa/WrapperBooleanJpa-description.adoc
new file mode 100644
index 0000000..f3a3b58
--- /dev/null
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/booleans/jpa/WrapperBooleanJpa-description.adoc
@@ -0,0 +1,24 @@
+: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 [...]
+
+[WARNING]
+==== 
+TODO this yet is just a copy from JDO
+====
+
+JDO supports `Boolean` link:http://www.datanucleus.org:15080/products/accessplatform_5_2/jdo/mapping.html#_primitive_and_java_lang_types[out-of-the-box], so no special annotations are required.
+
+[source,java]
+----
+include::WrapperBooleanJpa.java[tags=class]
+----
+<.> a no-arg constructor is introduced by JDO enhancer
+<.> required property as defined to JDO/DataNucleus.
++
+Apache Isis assumes properties are mandatory, so no additional annotation is required.
+<.> directly editable property as defined to Apache Isis
+<.> optional property as defined to Apache Isis
+<.> optional property as defined to JDO/DataNucleus
+
+
+
+include::../WrapperBooleans-common.adoc[]
\ No newline at end of file
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/booleans/jpa/WrapperBooleanJpa.java b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/booleans/jpa/WrapperBooleanJpa.java
new file mode 100644
index 0000000..1948ecc
--- /dev/null
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/booleans/jpa/WrapperBooleanJpa.java
@@ -0,0 +1,95 @@
+/*
+ *  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 demoapp.dom.types.javalang.booleans.jpa;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EntityListeners;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import org.springframework.context.annotation.Profile;
+
+import org.apache.isis.applib.annotation.DomainObject;
+import org.apache.isis.applib.annotation.Editing;
+import org.apache.isis.applib.annotation.Optionality;
+import org.apache.isis.applib.annotation.Property;
+import org.apache.isis.applib.annotation.PropertyLayout;
+import org.apache.isis.applib.annotation.Title;
+import org.apache.isis.persistence.jpa.applib.integration.JpaEntityInjectionPointResolver;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import demoapp.dom.types.javalang.booleans.persistence.WrapperBooleanEntity;
+
+@Profile("demo-jpa")
+//tag::class[]
+@Entity
+@Table(
+      schema = "demo",
+      name = "JavaLangStringJpa"
+)
+@EntityListeners(JpaEntityInjectionPointResolver.class)
+@DomainObject(
+      objectType = "demo.WrapperBooleanEntity"
+)
+@NoArgsConstructor
+public class WrapperBooleanJpa
+        extends WrapperBooleanEntity {
+
+//end::class[]
+    public WrapperBooleanJpa(Boolean initialValue) {
+        this.readOnlyProperty = initialValue;
+        this.readWriteProperty = initialValue;
+    }
+
+//tag::class[]
+    @Id
+    @GeneratedValue
+    private Long id;
+
+    @Title(prepend = "Boolean (wrapper) JDO entity: ")
+    @PropertyLayout(fieldSetId = "read-only-properties", sequence = "1")
+    @Column(nullable = false)                                                   // <.>
+    @Getter @Setter
+    private Boolean readOnlyProperty;
+
+    @Property(editing = Editing.ENABLED)                                        // <.>
+    @PropertyLayout(fieldSetId = "editable-properties", sequence = "1")
+    @Column(nullable = false)
+    @Getter @Setter
+    private Boolean readWriteProperty;
+
+    @Property(optionality = Optionality.OPTIONAL)                               // <.>
+    @PropertyLayout(fieldSetId = "optional-properties", sequence = "1")
+    @Column(nullable = true)                                                    // <.>
+    @Getter @Setter
+    private Boolean readOnlyOptionalProperty;
+
+    @Property(editing = Editing.ENABLED, optionality = Optionality.OPTIONAL)
+    @PropertyLayout(fieldSetId = "optional-properties", sequence = "2")
+    @Column(nullable = true)
+    @Getter @Setter
+    private Boolean readWriteOptionalProperty;
+
+}
+//end::class[]
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/DemoModuleJpa.java b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/booleans/jpa/WrapperBooleanJpaEntities.java
similarity index 65%
copy from examples/demo/domain/src/main/java/demoapp/dom/DemoModuleJpa.java
copy to examples/demo/domain/src/main/java/demoapp/dom/types/javalang/booleans/jpa/WrapperBooleanJpaEntities.java
index f2a9c94..59ca147 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/DemoModuleJpa.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/booleans/jpa/WrapperBooleanJpaEntities.java
@@ -16,22 +16,25 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package demoapp.dom;
+package demoapp.dom.types.javalang.booleans.jpa;
 
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Import;
 import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Service;
 
-import org.apache.isis.extensions.commandlog.jpa.IsisModuleExtCommandLogJpa;
-import org.apache.isis.persistence.jpa.eclipselink.IsisModuleJpaEclipselink;
+import demoapp.dom._infra.values.ValueHolderRepository;
 
-@Configuration
 @Profile("demo-jpa")
-@Import({
-    DemoModuleCommon.class,
-    IsisModuleJpaEclipselink.class,
-    IsisModuleExtCommandLogJpa.class,
-})
-public class DemoModuleJpa {
+@Service
+public class WrapperBooleanJpaEntities
+extends ValueHolderRepository<Boolean, WrapperBooleanJpa> {
+
+    protected WrapperBooleanJpaEntities() {
+        super(WrapperBooleanJpa.class);
+    }
+
+    @Override
+    protected WrapperBooleanJpa newDetachedEntity(Boolean value) {
+        return new WrapperBooleanJpa(value);
+    }
 
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/bytes/WrapperBytes.java b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/bytes/WrapperBytes.java
index 36a846c..8786518 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/bytes/WrapperBytes.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/bytes/WrapperBytes.java
@@ -36,18 +36,16 @@ import org.apache.isis.applib.annotation.Nature;
 import org.apache.isis.applib.annotation.PromptStyle;
 import org.apache.isis.applib.annotation.SemanticsOf;
 
-import lombok.extern.log4j.Log4j2;
-
 import demoapp.dom._infra.asciidocdesc.HasAsciiDocDescription;
-import demoapp.dom.types.javalang.bytes.jdo.WrapperByteJdo;
-import demoapp.dom.types.javalang.bytes.jdo.WrapperByteJdoEntities;
+import demoapp.dom._infra.values.ValueHolderRepository;
+import demoapp.dom.types.javalang.bytes.persistence.WrapperByteEntity;
 import demoapp.dom.types.javalang.bytes.vm.WrapperByteVm;
 
 @XmlRootElement(name = "Demo")
 @XmlType
 @XmlAccessorType(XmlAccessType.FIELD)
 @DomainObject(nature=Nature.VIEW_MODEL, objectType = "demo.WrapperBytes", editing=Editing.ENABLED)
-@Log4j2
+//@Log4j2
 public class WrapperBytes implements HasAsciiDocDescription {
 
     public String title() {
@@ -64,13 +62,13 @@ public class WrapperBytes implements HasAsciiDocDescription {
     }
 
     @Collection
-    public List<WrapperByteJdo> getEntities() {
+    public List<? extends WrapperByteEntity> getEntities() {
         return entities.all();
     }
 
     @Inject
     @XmlTransient
-    WrapperByteJdoEntities entities;
+    ValueHolderRepository<Byte, ? extends WrapperByteEntity> entities;
 
 
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/bytes/jpa/WrapperByteJpa-description.adoc b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/bytes/jpa/WrapperByteJpa-description.adoc
new file mode 100644
index 0000000..bd120c2
--- /dev/null
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/bytes/jpa/WrapperByteJpa-description.adoc
@@ -0,0 +1,23 @@
+: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 [...]
+
+[WARNING]
+==== 
+TODO this yet is just a copy from JDO
+====
+
+JDO supports `Byte` link:http://www.datanucleus.org:15080/products/accessplatform_5_2/jdo/mapping.html#_primitive_and_java_lang_types[out-of-the-box], so no special annotations are required.
+
+[source,java]
+----
+include::WrapperByteJpa.java[tags=class]
+----
+<.> a no-arg constructor is introduced by JDO enhancer
+<.> required property as defined to JDO/DataNucleus.
++
+Apache Isis assumes properties are mandatory, so no additional annotation is required.
+<.> directly editable property as defined to Apache Isis
+<.> optional property as defined to Apache Isis
+<.> optional property as defined to JDO/DataNucleus
+
+
+include::../WrapperBytes-common.adoc[]
\ No newline at end of file
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/bytes/jpa/WrapperByteJpa.java b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/bytes/jpa/WrapperByteJpa.java
new file mode 100644
index 0000000..05ac80c
--- /dev/null
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/bytes/jpa/WrapperByteJpa.java
@@ -0,0 +1,95 @@
+/*
+ *  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 demoapp.dom.types.javalang.bytes.jpa;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EntityListeners;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import org.springframework.context.annotation.Profile;
+
+import org.apache.isis.applib.annotation.DomainObject;
+import org.apache.isis.applib.annotation.Editing;
+import org.apache.isis.applib.annotation.Optionality;
+import org.apache.isis.applib.annotation.Property;
+import org.apache.isis.applib.annotation.PropertyLayout;
+import org.apache.isis.applib.annotation.Title;
+import org.apache.isis.persistence.jpa.applib.integration.JpaEntityInjectionPointResolver;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import demoapp.dom.types.javalang.bytes.persistence.WrapperByteEntity;
+
+@Profile("demo-jpa")
+//tag::class[]
+@Entity
+@Table(
+      schema = "demo",
+      name = "JavaLangStringJpa"
+)
+@EntityListeners(JpaEntityInjectionPointResolver.class)
+@DomainObject(
+      objectType = "demo.WrapperByteEntity"
+)
+@NoArgsConstructor
+public class WrapperByteJpa
+        extends WrapperByteEntity {
+
+//end::class[]
+    public WrapperByteJpa(Byte initialValue) {
+        this.readOnlyProperty = initialValue;
+        this.readWriteProperty = initialValue;
+    }
+
+//tag::class[]
+    @Id
+    @GeneratedValue
+    private Long id;
+
+    @Title(prepend = "Byte (wrapper) JDO entity: ")
+    @PropertyLayout(fieldSetId = "read-only-properties", sequence = "1")
+    @Column(nullable = false)                                                   // <.>
+    @Getter @Setter
+    private Byte readOnlyProperty;
+
+    @Property(editing = Editing.ENABLED)                                        // <.>
+    @PropertyLayout(fieldSetId = "editable-properties", sequence = "1")
+    @Column(nullable = false)
+    @Getter @Setter
+    private Byte readWriteProperty;
+
+    @Property(optionality = Optionality.OPTIONAL)                               // <.>
+    @PropertyLayout(fieldSetId = "optional-properties", sequence = "1")
+    @Column(nullable = true)                                                    // <.>
+    @Getter @Setter
+    private Byte readOnlyOptionalProperty;
+
+    @Property(editing = Editing.ENABLED, optionality = Optionality.OPTIONAL)
+    @PropertyLayout(fieldSetId = "optional-properties", sequence = "2")
+    @Column(nullable = true)
+    @Getter @Setter
+    private Byte readWriteOptionalProperty;
+
+}
+//end::class[]
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/DemoModuleJpa.java b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/bytes/jpa/WrapperByteJpaEntities.java
similarity index 66%
copy from examples/demo/domain/src/main/java/demoapp/dom/DemoModuleJpa.java
copy to examples/demo/domain/src/main/java/demoapp/dom/types/javalang/bytes/jpa/WrapperByteJpaEntities.java
index f2a9c94..a26ab9d 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/DemoModuleJpa.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/bytes/jpa/WrapperByteJpaEntities.java
@@ -16,22 +16,25 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package demoapp.dom;
+package demoapp.dom.types.javalang.bytes.jpa;
 
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Import;
 import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Service;
 
-import org.apache.isis.extensions.commandlog.jpa.IsisModuleExtCommandLogJpa;
-import org.apache.isis.persistence.jpa.eclipselink.IsisModuleJpaEclipselink;
+import demoapp.dom._infra.values.ValueHolderRepository;
 
-@Configuration
 @Profile("demo-jpa")
-@Import({
-    DemoModuleCommon.class,
-    IsisModuleJpaEclipselink.class,
-    IsisModuleExtCommandLogJpa.class,
-})
-public class DemoModuleJpa {
+@Service
+public class WrapperByteJpaEntities
+extends ValueHolderRepository<Byte, WrapperByteJpa> {
+
+    protected WrapperByteJpaEntities() {
+        super(WrapperByteJpa.class);
+    }
+
+    @Override
+    protected WrapperByteJpa newDetachedEntity(Byte value) {
+        return new WrapperByteJpa(value);
+    }
 
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/characters/WrapperCharacters.java b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/characters/WrapperCharacters.java
index e3c447d..5a6ad9e 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/characters/WrapperCharacters.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/characters/WrapperCharacters.java
@@ -36,18 +36,16 @@ import org.apache.isis.applib.annotation.Nature;
 import org.apache.isis.applib.annotation.PromptStyle;
 import org.apache.isis.applib.annotation.SemanticsOf;
 
-import lombok.extern.log4j.Log4j2;
-
 import demoapp.dom._infra.asciidocdesc.HasAsciiDocDescription;
-import demoapp.dom.types.javalang.characters.jdo.WrapperCharacterJdo;
-import demoapp.dom.types.javalang.characters.jdo.WrapperCharacterJdoEntities;
+import demoapp.dom._infra.values.ValueHolderRepository;
+import demoapp.dom.types.javalang.characters.persistence.WrapperCharacterEntity;
 import demoapp.dom.types.javalang.characters.vm.WrapperCharacterVm;
 
 @XmlRootElement(name = "Demo")
 @XmlType
 @XmlAccessorType(XmlAccessType.FIELD)
 @DomainObject(nature=Nature.VIEW_MODEL, objectType = "demo.WrapperCharacters", editing=Editing.ENABLED)
-@Log4j2
+//@Log4j2
 public class WrapperCharacters implements HasAsciiDocDescription {
 
     public String title() {
@@ -64,13 +62,13 @@ public class WrapperCharacters implements HasAsciiDocDescription {
     }
 
     @Collection
-    public List<WrapperCharacterJdo> getEntities() {
+    public List<? extends WrapperCharacterEntity> getEntities() {
         return entities.all();
     }
 
     @Inject
     @XmlTransient
-    WrapperCharacterJdoEntities entities;
+    ValueHolderRepository<Character, ? extends WrapperCharacterEntity> entities;
 
 
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/characters/jpa/WrapperCharacterJpa-description.adoc b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/characters/jpa/WrapperCharacterJpa-description.adoc
new file mode 100644
index 0000000..64d5b45
--- /dev/null
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/characters/jpa/WrapperCharacterJpa-description.adoc
@@ -0,0 +1,23 @@
+: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 [...]
+
+[WARNING]
+==== 
+TODO this yet is just a copy from JDO
+====
+
+JDO supports `Character` link:http://www.datanucleus.org:15080/products/accessplatform_5_2/jdo/mapping.html#_primitive_and_java_lang_types[out-of-the-box], so no special annotations are required.
+
+[source,java]
+----
+include::WrapperCharacterJpa.java[tags=class]
+----
+<.> a no-arg constructor is introduced by JDO enhancer
+<.> required property as defined to JDO/DataNucleus.
++
+Apache Isis assumes properties are mandatory, so no additional annotation is required.
+<.> directly editable property as defined to Apache Isis
+<.> optional property as defined to Apache Isis
+<.> optional property as defined to JDO/DataNucleus
+
+
+include::../WrapperCharacters-common.adoc[]
\ No newline at end of file
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/characters/jpa/WrapperCharacterJpa.java b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/characters/jpa/WrapperCharacterJpa.java
new file mode 100644
index 0000000..a938022
--- /dev/null
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/characters/jpa/WrapperCharacterJpa.java
@@ -0,0 +1,95 @@
+/*
+ *  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 demoapp.dom.types.javalang.characters.jpa;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EntityListeners;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import org.springframework.context.annotation.Profile;
+
+import org.apache.isis.applib.annotation.DomainObject;
+import org.apache.isis.applib.annotation.Editing;
+import org.apache.isis.applib.annotation.Optionality;
+import org.apache.isis.applib.annotation.Property;
+import org.apache.isis.applib.annotation.PropertyLayout;
+import org.apache.isis.applib.annotation.Title;
+import org.apache.isis.persistence.jpa.applib.integration.JpaEntityInjectionPointResolver;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import demoapp.dom.types.javalang.characters.persistence.WrapperCharacterEntity;
+
+@Profile("demo-jpa")
+//tag::class[]
+@Entity
+@Table(
+      schema = "demo",
+      name = "JavaLangStringJpa"
+)
+@EntityListeners(JpaEntityInjectionPointResolver.class)
+@DomainObject(
+      objectType = "demo.WrapperCharacterEntity"
+)
+@NoArgsConstructor
+public class WrapperCharacterJpa
+        extends WrapperCharacterEntity {
+
+//end::class[]
+    public WrapperCharacterJpa(Character initialValue) {
+        this.readOnlyProperty = initialValue;
+        this.readWriteProperty = initialValue;
+    }
+
+//tag::class[]
+    @Id
+    @GeneratedValue
+    private Long id;
+
+    @Title(prepend = "Character (wrapper) JDO entity: ")
+    @PropertyLayout(fieldSetId = "read-only-properties", sequence = "1")
+    @Column(nullable = false)                                                   // <.>
+    @Getter @Setter
+    private Character readOnlyProperty;
+
+    @Property(editing = Editing.ENABLED)                                        // <.>
+    @PropertyLayout(fieldSetId = "editable-properties", sequence = "1")
+    @Column(nullable = false)
+    @Getter @Setter
+    private Character readWriteProperty;
+
+    @Property(optionality = Optionality.OPTIONAL)                               // <.>
+    @PropertyLayout(fieldSetId = "optional-properties", sequence = "1")
+    @Column(nullable = true)                                                    // <.>
+    @Getter @Setter
+    private Character readOnlyOptionalProperty;
+
+    @Property(editing = Editing.ENABLED, optionality = Optionality.OPTIONAL)
+    @PropertyLayout(fieldSetId = "optional-properties", sequence = "2")
+    @Column(nullable = true)
+    @Getter @Setter
+    private Character readWriteOptionalProperty;
+
+}
+//end::class[]
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/DemoModuleJpa.java b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/characters/jpa/WrapperCharacterJpaEntities.java
similarity index 64%
copy from examples/demo/domain/src/main/java/demoapp/dom/DemoModuleJpa.java
copy to examples/demo/domain/src/main/java/demoapp/dom/types/javalang/characters/jpa/WrapperCharacterJpaEntities.java
index f2a9c94..0ff7e64 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/DemoModuleJpa.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/characters/jpa/WrapperCharacterJpaEntities.java
@@ -16,22 +16,25 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package demoapp.dom;
+package demoapp.dom.types.javalang.characters.jpa;
 
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Import;
 import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Service;
 
-import org.apache.isis.extensions.commandlog.jpa.IsisModuleExtCommandLogJpa;
-import org.apache.isis.persistence.jpa.eclipselink.IsisModuleJpaEclipselink;
+import demoapp.dom._infra.values.ValueHolderRepository;
 
-@Configuration
 @Profile("demo-jpa")
-@Import({
-    DemoModuleCommon.class,
-    IsisModuleJpaEclipselink.class,
-    IsisModuleExtCommandLogJpa.class,
-})
-public class DemoModuleJpa {
+@Service
+public class WrapperCharacterJpaEntities
+extends ValueHolderRepository<Character, WrapperCharacterJpa> {
+
+    protected WrapperCharacterJpaEntities() {
+        super(WrapperCharacterJpa.class);
+    }
+
+    @Override
+    protected WrapperCharacterJpa newDetachedEntity(Character value) {
+        return new WrapperCharacterJpa(value);
+    }
 
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/doubles/WrapperDoubles.java b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/doubles/WrapperDoubles.java
index 01d20ae..f58be17 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/doubles/WrapperDoubles.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/doubles/WrapperDoubles.java
@@ -36,18 +36,16 @@ import org.apache.isis.applib.annotation.Nature;
 import org.apache.isis.applib.annotation.PromptStyle;
 import org.apache.isis.applib.annotation.SemanticsOf;
 
-import lombok.extern.log4j.Log4j2;
-
 import demoapp.dom._infra.asciidocdesc.HasAsciiDocDescription;
-import demoapp.dom.types.javalang.doubles.jdo.WrapperDoubleJdo;
-import demoapp.dom.types.javalang.doubles.jdo.WrapperDoubleJdoEntities;
+import demoapp.dom._infra.values.ValueHolderRepository;
+import demoapp.dom.types.javalang.doubles.persistence.WrapperDoubleEntity;
 import demoapp.dom.types.javalang.doubles.vm.WrapperDoubleVm;
 
 @XmlRootElement(name = "Demo")
 @XmlType
 @XmlAccessorType(XmlAccessType.FIELD)
 @DomainObject(nature=Nature.VIEW_MODEL, objectType = "demo.WrapperDoubles", editing=Editing.ENABLED)
-@Log4j2
+//@Log4j2
 public class WrapperDoubles implements HasAsciiDocDescription {
 
     public String title() {
@@ -64,13 +62,13 @@ public class WrapperDoubles implements HasAsciiDocDescription {
     }
 
     @Collection
-    public List<WrapperDoubleJdo> getEntities() {
+    public List<? extends WrapperDoubleEntity> getEntities() {
         return entities.all();
     }
 
     @Inject
     @XmlTransient
-    WrapperDoubleJdoEntities entities;
+    ValueHolderRepository<Double, ? extends WrapperDoubleEntity> entities;
 
 
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/doubles/jpa/WrapperDoubleJpa-description.adoc b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/doubles/jpa/WrapperDoubleJpa-description.adoc
new file mode 100644
index 0000000..a9cc50c
--- /dev/null
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/doubles/jpa/WrapperDoubleJpa-description.adoc
@@ -0,0 +1,23 @@
+: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 [...]
+
+[WARNING]
+==== 
+TODO this yet is just a copy from JDO
+====
+
+JDO supports `Double` link:http://www.datanucleus.org:15080/products/accessplatform_5_2/jdo/mapping.html#_primitive_and_java_lang_types[out-of-the-box], so no special annotations are required.
+
+[source,java]
+----
+include::WrapperDoubleJpa.java[tags=class]
+----
+<.> a no-arg constructor is introduced by JDO enhancer
+<.> required property as defined to JDO/DataNucleus.
++
+Apache Isis assumes properties are mandatory, so no additional annotation is required.
+<.> directly editable property as defined to Apache Isis
+<.> optional property as defined to Apache Isis
+<.> optional property as defined to JDO/DataNucleus
+
+
+include::../WrapperDoubles-common.adoc[]
\ No newline at end of file
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/doubles/jpa/WrapperDoubleJpa.java b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/doubles/jpa/WrapperDoubleJpa.java
new file mode 100644
index 0000000..dc55c0b
--- /dev/null
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/doubles/jpa/WrapperDoubleJpa.java
@@ -0,0 +1,95 @@
+/*
+ *  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 demoapp.dom.types.javalang.doubles.jpa;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EntityListeners;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import org.springframework.context.annotation.Profile;
+
+import org.apache.isis.applib.annotation.DomainObject;
+import org.apache.isis.applib.annotation.Editing;
+import org.apache.isis.applib.annotation.Optionality;
+import org.apache.isis.applib.annotation.Property;
+import org.apache.isis.applib.annotation.PropertyLayout;
+import org.apache.isis.applib.annotation.Title;
+import org.apache.isis.persistence.jpa.applib.integration.JpaEntityInjectionPointResolver;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import demoapp.dom.types.javalang.doubles.persistence.WrapperDoubleEntity;
+
+@Profile("demo-jpa")
+//tag::class[]
+@Entity
+@Table(
+      schema = "demo",
+      name = "JavaLangStringJpa"
+)
+@EntityListeners(JpaEntityInjectionPointResolver.class)
+@DomainObject(
+      objectType = "demo.WrapperDoubleEntity"
+)
+@NoArgsConstructor
+public class WrapperDoubleJpa
+        extends WrapperDoubleEntity {
+
+//end::class[]
+    public WrapperDoubleJpa(Double initialValue) {
+        this.readOnlyProperty = initialValue;
+        this.readWriteProperty = initialValue;
+    }
+
+//tag::class[]
+    @Id
+    @GeneratedValue
+    private Long id;
+
+    @Title(prepend = "Double (wrapper) JDO entity: ")
+    @PropertyLayout(fieldSetId = "read-only-properties", sequence = "1")
+    @Column(nullable = false)                                                   // <.>
+    @Getter @Setter
+    private Double readOnlyProperty;
+
+    @Property(editing = Editing.ENABLED)                                        // <.>
+    @PropertyLayout(fieldSetId = "editable-properties", sequence = "1")
+    @Column(nullable = false)
+    @Getter @Setter
+    private Double readWriteProperty;
+
+    @Property(optionality = Optionality.OPTIONAL)                               // <.>
+    @PropertyLayout(fieldSetId = "optional-properties", sequence = "1")
+    @Column(nullable = true)                                                    // <.>
+    @Getter @Setter
+    private Double readOnlyOptionalProperty;
+
+    @Property(editing = Editing.ENABLED, optionality = Optionality.OPTIONAL)
+    @PropertyLayout(fieldSetId = "optional-properties", sequence = "2")
+    @Column(nullable = true)
+    @Getter @Setter
+    private Double readWriteOptionalProperty;
+
+}
+//end::class[]
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/DemoModuleJpa.java b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/doubles/jpa/WrapperDoubleJpaEntities.java
similarity index 65%
copy from examples/demo/domain/src/main/java/demoapp/dom/DemoModuleJpa.java
copy to examples/demo/domain/src/main/java/demoapp/dom/types/javalang/doubles/jpa/WrapperDoubleJpaEntities.java
index f2a9c94..f1dba73 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/DemoModuleJpa.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/doubles/jpa/WrapperDoubleJpaEntities.java
@@ -16,22 +16,25 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package demoapp.dom;
+package demoapp.dom.types.javalang.doubles.jpa;
 
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Import;
 import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Service;
 
-import org.apache.isis.extensions.commandlog.jpa.IsisModuleExtCommandLogJpa;
-import org.apache.isis.persistence.jpa.eclipselink.IsisModuleJpaEclipselink;
+import demoapp.dom._infra.values.ValueHolderRepository;
 
-@Configuration
 @Profile("demo-jpa")
-@Import({
-    DemoModuleCommon.class,
-    IsisModuleJpaEclipselink.class,
-    IsisModuleExtCommandLogJpa.class,
-})
-public class DemoModuleJpa {
+@Service
+public class WrapperDoubleJpaEntities
+extends ValueHolderRepository<Double, WrapperDoubleJpa> {
+
+    protected WrapperDoubleJpaEntities() {
+        super(WrapperDoubleJpa.class);
+    }
+
+    @Override
+    protected WrapperDoubleJpa newDetachedEntity(Double value) {
+        return new WrapperDoubleJpa(value);
+    }
 
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/floats/WrapperFloats.java b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/floats/WrapperFloats.java
index 952d69b..86a3d12 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/floats/WrapperFloats.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/floats/WrapperFloats.java
@@ -36,18 +36,16 @@ import org.apache.isis.applib.annotation.Nature;
 import org.apache.isis.applib.annotation.PromptStyle;
 import org.apache.isis.applib.annotation.SemanticsOf;
 
-import lombok.extern.log4j.Log4j2;
-
 import demoapp.dom._infra.asciidocdesc.HasAsciiDocDescription;
-import demoapp.dom.types.javalang.floats.jdo.WrapperFloatJdo;
-import demoapp.dom.types.javalang.floats.jdo.WrapperFloatJdoEntities;
+import demoapp.dom._infra.values.ValueHolderRepository;
+import demoapp.dom.types.javalang.floats.persistence.WrapperFloatEntity;
 import demoapp.dom.types.javalang.floats.vm.WrapperFloatVm;
 
 @XmlRootElement(name = "Demo")
 @XmlType
 @XmlAccessorType(XmlAccessType.FIELD)
 @DomainObject(nature=Nature.VIEW_MODEL, objectType = "demo.WrapperFloats", editing=Editing.ENABLED)
-@Log4j2
+//@Log4j2
 public class WrapperFloats implements HasAsciiDocDescription {
 
     public String title() {
@@ -64,13 +62,13 @@ public class WrapperFloats implements HasAsciiDocDescription {
     }
 
     @Collection
-    public List<WrapperFloatJdo> getEntities() {
+    public List<? extends WrapperFloatEntity> getEntities() {
         return entities.all();
     }
 
     @Inject
     @XmlTransient
-    WrapperFloatJdoEntities entities;
+    ValueHolderRepository<Float, ? extends WrapperFloatEntity> entities;
 
 
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/floats/jpa/WrapperFloatJpa-description.adoc b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/floats/jpa/WrapperFloatJpa-description.adoc
new file mode 100644
index 0000000..0ecbb89
--- /dev/null
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/floats/jpa/WrapperFloatJpa-description.adoc
@@ -0,0 +1,23 @@
+: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 [...]
+
+[WARNING]
+==== 
+TODO this yet is just a copy from JDO
+====
+
+JDO supports `Float` link:http://www.datanucleus.org:15080/products/accessplatform_5_2/jdo/mapping.html#_primitive_and_java_lang_types[out-of-the-box], so no special annotations are required.
+
+[source,java]
+----
+include::WrapperFloatJpa.java[tags=class]
+----
+<.> a no-arg constructor is introduced by JDO enhancer
+<.> required property as defined to JDO/DataNucleus.
++
+Apache Isis assumes properties are mandatory, so no additional annotation is required.
+<.> directly editable property as defined to Apache Isis
+<.> optional property as defined to Apache Isis
+<.> optional property as defined to JDO/DataNucleus
+
+
+include::../WrapperFloats-common.adoc[]
\ No newline at end of file
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/floats/jpa/WrapperFloatJpa.java b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/floats/jpa/WrapperFloatJpa.java
new file mode 100644
index 0000000..28e893e
--- /dev/null
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/floats/jpa/WrapperFloatJpa.java
@@ -0,0 +1,95 @@
+/*
+ *  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 demoapp.dom.types.javalang.floats.jpa;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EntityListeners;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import org.springframework.context.annotation.Profile;
+
+import org.apache.isis.applib.annotation.DomainObject;
+import org.apache.isis.applib.annotation.Editing;
+import org.apache.isis.applib.annotation.Optionality;
+import org.apache.isis.applib.annotation.Property;
+import org.apache.isis.applib.annotation.PropertyLayout;
+import org.apache.isis.applib.annotation.Title;
+import org.apache.isis.persistence.jpa.applib.integration.JpaEntityInjectionPointResolver;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import demoapp.dom.types.javalang.floats.persistence.WrapperFloatEntity;
+
+@Profile("demo-jpa")
+//tag::class[]
+@Entity
+@Table(
+      schema = "demo",
+      name = "JavaLangStringJpa"
+)
+@EntityListeners(JpaEntityInjectionPointResolver.class)
+@DomainObject(
+      objectType = "demo.WrapperFloatEntity"
+)
+@NoArgsConstructor
+public class WrapperFloatJpa
+        extends WrapperFloatEntity {
+
+//end::class[]
+    public WrapperFloatJpa(Float initialValue) {
+        this.readOnlyProperty = initialValue;
+        this.readWriteProperty = initialValue;
+    }
+
+//tag::class[]
+    @Id
+    @GeneratedValue
+    private Long id;
+
+    @Title(prepend = "Float (wrapper) JDO entity: ")
+    @PropertyLayout(fieldSetId = "read-only-properties", sequence = "1")
+    @Column(nullable = false)                                                   // <.>
+    @Getter @Setter
+    private Float readOnlyProperty;
+
+    @Property(editing = Editing.ENABLED)                                        // <.>
+    @PropertyLayout(fieldSetId = "editable-properties", sequence = "1")
+    @Column(nullable = false)
+    @Getter @Setter
+    private Float readWriteProperty;
+
+    @Property(optionality = Optionality.OPTIONAL)                               // <.>
+    @PropertyLayout(fieldSetId = "optional-properties", sequence = "1")
+    @Column(nullable = true)                                                    // <.>
+    @Getter @Setter
+    private Float readOnlyOptionalProperty;
+
+    @Property(editing = Editing.ENABLED, optionality = Optionality.OPTIONAL)
+    @PropertyLayout(fieldSetId = "optional-properties", sequence = "2")
+    @Column(nullable = true)
+    @Getter @Setter
+    private Float readWriteOptionalProperty;
+
+}
+//end::class[]
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/DemoModuleJpa.java b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/floats/jpa/WrapperFloatJpaEntities.java
similarity index 65%
copy from examples/demo/domain/src/main/java/demoapp/dom/DemoModuleJpa.java
copy to examples/demo/domain/src/main/java/demoapp/dom/types/javalang/floats/jpa/WrapperFloatJpaEntities.java
index f2a9c94..2d4f786 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/DemoModuleJpa.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/floats/jpa/WrapperFloatJpaEntities.java
@@ -16,22 +16,25 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package demoapp.dom;
+package demoapp.dom.types.javalang.floats.jpa;
 
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Import;
 import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Service;
 
-import org.apache.isis.extensions.commandlog.jpa.IsisModuleExtCommandLogJpa;
-import org.apache.isis.persistence.jpa.eclipselink.IsisModuleJpaEclipselink;
+import demoapp.dom._infra.values.ValueHolderRepository;
 
-@Configuration
 @Profile("demo-jpa")
-@Import({
-    DemoModuleCommon.class,
-    IsisModuleJpaEclipselink.class,
-    IsisModuleExtCommandLogJpa.class,
-})
-public class DemoModuleJpa {
+@Service
+public class WrapperFloatJpaEntities
+extends ValueHolderRepository<Float, WrapperFloatJpa> {
 
-}
+    protected WrapperFloatJpaEntities() {
+        super(WrapperFloatJpa.class);
+    }
+
+    @Override
+    protected WrapperFloatJpa newDetachedEntity(Float value) {
+        return new WrapperFloatJpa(value);
+    }
+
+}
\ No newline at end of file
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/integers/WrapperIntegers.java b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/integers/WrapperIntegers.java
index ecb54d7..42f21f6 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/integers/WrapperIntegers.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/integers/WrapperIntegers.java
@@ -36,18 +36,16 @@ import org.apache.isis.applib.annotation.Nature;
 import org.apache.isis.applib.annotation.PromptStyle;
 import org.apache.isis.applib.annotation.SemanticsOf;
 
-import lombok.extern.log4j.Log4j2;
-
 import demoapp.dom._infra.asciidocdesc.HasAsciiDocDescription;
-import demoapp.dom.types.javalang.integers.jdo.WrapperIntegerJdo;
-import demoapp.dom.types.javalang.integers.jdo.WrapperIntegerJdoEntities;
+import demoapp.dom._infra.values.ValueHolderRepository;
+import demoapp.dom.types.javalang.integers.persistence.WrapperIntegerEntity;
 import demoapp.dom.types.javalang.integers.vm.WrapperIntegerVm;
 
 @XmlRootElement(name = "Demo")
 @XmlType
 @XmlAccessorType(XmlAccessType.FIELD)
 @DomainObject(nature=Nature.VIEW_MODEL, objectType = "demo.WrapperIntegers", editing=Editing.ENABLED)
-@Log4j2
+//@Log4j2
 public class WrapperIntegers implements HasAsciiDocDescription {
 
     public String title() {
@@ -64,13 +62,13 @@ public class WrapperIntegers implements HasAsciiDocDescription {
     }
 
     @Collection
-    public List<WrapperIntegerJdo> getEntities() {
+    public List<? extends WrapperIntegerEntity> getEntities() {
         return entities.all();
     }
 
     @Inject
     @XmlTransient
-    WrapperIntegerJdoEntities entities;
+    ValueHolderRepository<Integer, ? extends WrapperIntegerEntity> entities;
 
 
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/integers/jpa/WrapperIntegerJpa-description.adoc b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/integers/jpa/WrapperIntegerJpa-description.adoc
new file mode 100644
index 0000000..e28f351
--- /dev/null
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/integers/jpa/WrapperIntegerJpa-description.adoc
@@ -0,0 +1,23 @@
+: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 [...]
+
+[WARNING]
+==== 
+TODO this yet is just a copy from JDO
+====
+
+JDO supports `Integer` link:http://www.datanucleus.org:15080/products/accessplatform_5_2/jdo/mapping.html#_primitive_and_java_lang_types[out-of-the-box], so no special annotations are required.
+
+[source,java]
+----
+include::WrapperIntegerJpa.java[tags=class]
+----
+<.> a no-arg constructor is introduced by JDO enhancer
+<.> required property as defined to JDO/DataNucleus.
++
+Apache Isis assumes properties are mandatory, so no additional annotation is required.
+<.> directly editable property as defined to Apache Isis
+<.> optional property as defined to Apache Isis
+<.> optional property as defined to JDO/DataNucleus
+
+
+include::../WrapperIntegers-common.adoc[]
\ No newline at end of file
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/integers/jpa/WrapperIntegerJpa.java b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/integers/jpa/WrapperIntegerJpa.java
new file mode 100644
index 0000000..0b83de2
--- /dev/null
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/integers/jpa/WrapperIntegerJpa.java
@@ -0,0 +1,95 @@
+/*
+ *  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 demoapp.dom.types.javalang.integers.jpa;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EntityListeners;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import org.springframework.context.annotation.Profile;
+
+import org.apache.isis.applib.annotation.DomainObject;
+import org.apache.isis.applib.annotation.Editing;
+import org.apache.isis.applib.annotation.Optionality;
+import org.apache.isis.applib.annotation.Property;
+import org.apache.isis.applib.annotation.PropertyLayout;
+import org.apache.isis.applib.annotation.Title;
+import org.apache.isis.persistence.jpa.applib.integration.JpaEntityInjectionPointResolver;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import demoapp.dom.types.javalang.integers.persistence.WrapperIntegerEntity;
+
+@Profile("demo-jpa")
+//tag::class[]
+@Entity
+@Table(
+      schema = "demo",
+      name = "JavaLangStringJpa"
+)
+@EntityListeners(JpaEntityInjectionPointResolver.class)
+@DomainObject(
+      objectType = "demo.WrapperIntegerEntity"
+)
+@NoArgsConstructor
+public class WrapperIntegerJpa
+        extends WrapperIntegerEntity {
+
+//end::class[]
+    public WrapperIntegerJpa(Integer initialValue) {
+        this.readOnlyProperty = initialValue;
+        this.readWriteProperty = initialValue;
+    }
+
+//tag::class[]
+    @Id
+    @GeneratedValue
+    private Long id;
+
+    @Title(prepend = "Integer (wrapper) JDO entity: ")
+    @PropertyLayout(fieldSetId = "read-only-properties", sequence = "1")
+    @Column(nullable = false)                                                   // <.>
+    @Getter @Setter
+    private Integer readOnlyProperty;
+
+    @Property(editing = Editing.ENABLED)                                        // <.>
+    @PropertyLayout(fieldSetId = "editable-properties", sequence = "1")
+    @Column(nullable = false)
+    @Getter @Setter
+    private Integer readWriteProperty;
+
+    @Property(optionality = Optionality.OPTIONAL)                               // <.>
+    @PropertyLayout(fieldSetId = "optional-properties", sequence = "1")
+    @Column(nullable = true)                                                    // <.>
+    @Getter @Setter
+    private Integer readOnlyOptionalProperty;
+
+    @Property(editing = Editing.ENABLED, optionality = Optionality.OPTIONAL)
+    @PropertyLayout(fieldSetId = "optional-properties", sequence = "2")
+    @Column(nullable = true)
+    @Getter @Setter
+    private Integer readWriteOptionalProperty;
+
+}
+//end::class[]
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/DemoModuleJpa.java b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/integers/jpa/WrapperIntegerJpaEntities.java
similarity index 65%
copy from examples/demo/domain/src/main/java/demoapp/dom/DemoModuleJpa.java
copy to examples/demo/domain/src/main/java/demoapp/dom/types/javalang/integers/jpa/WrapperIntegerJpaEntities.java
index f2a9c94..0570528 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/DemoModuleJpa.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/integers/jpa/WrapperIntegerJpaEntities.java
@@ -16,22 +16,25 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package demoapp.dom;
+package demoapp.dom.types.javalang.integers.jpa;
 
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Import;
 import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Service;
 
-import org.apache.isis.extensions.commandlog.jpa.IsisModuleExtCommandLogJpa;
-import org.apache.isis.persistence.jpa.eclipselink.IsisModuleJpaEclipselink;
+import demoapp.dom._infra.values.ValueHolderRepository;
 
-@Configuration
 @Profile("demo-jpa")
-@Import({
-    DemoModuleCommon.class,
-    IsisModuleJpaEclipselink.class,
-    IsisModuleExtCommandLogJpa.class,
-})
-public class DemoModuleJpa {
+@Service
+public class WrapperIntegerJpaEntities
+extends ValueHolderRepository<Integer, WrapperIntegerJpa> {
+
+    protected WrapperIntegerJpaEntities() {
+        super(WrapperIntegerJpa.class);
+    }
+
+    @Override
+    protected WrapperIntegerJpa newDetachedEntity(Integer value) {
+        return new WrapperIntegerJpa(value);
+    }
 
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/longs/WrapperLongs.java b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/longs/WrapperLongs.java
index 80622e0..9fa8527 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/longs/WrapperLongs.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/longs/WrapperLongs.java
@@ -36,18 +36,16 @@ import org.apache.isis.applib.annotation.Nature;
 import org.apache.isis.applib.annotation.PromptStyle;
 import org.apache.isis.applib.annotation.SemanticsOf;
 
-import lombok.extern.log4j.Log4j2;
-
 import demoapp.dom._infra.asciidocdesc.HasAsciiDocDescription;
-import demoapp.dom.types.javalang.longs.jdo.WrapperLongJdo;
-import demoapp.dom.types.javalang.longs.jdo.WrapperLongJdoEntities;
+import demoapp.dom._infra.values.ValueHolderRepository;
+import demoapp.dom.types.javalang.longs.persistence.WrapperLongEntity;
 import demoapp.dom.types.javalang.longs.vm.WrapperLongVm;
 
 @XmlRootElement(name = "Demo")
 @XmlType
 @XmlAccessorType(XmlAccessType.FIELD)
 @DomainObject(nature=Nature.VIEW_MODEL, objectType = "demo.WrapperLongs", editing=Editing.ENABLED)
-@Log4j2
+//@Log4j2
 public class WrapperLongs implements HasAsciiDocDescription {
 
     public String title() {
@@ -64,13 +62,13 @@ public class WrapperLongs implements HasAsciiDocDescription {
     }
 
     @Collection
-    public List<WrapperLongJdo> getEntities() {
+    public List<? extends WrapperLongEntity> getEntities() {
         return entities.all();
     }
 
     @Inject
     @XmlTransient
-    WrapperLongJdoEntities entities;
+    ValueHolderRepository<Long, ? extends WrapperLongEntity> entities;
 
 
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/longs/jpa/WrapperLongJpa-description.adoc b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/longs/jpa/WrapperLongJpa-description.adoc
new file mode 100644
index 0000000..0207800
--- /dev/null
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/longs/jpa/WrapperLongJpa-description.adoc
@@ -0,0 +1,24 @@
+: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 [...]
+
+[WARNING]
+==== 
+TODO this yet is just a copy from JDO
+====
+
+JDO supports `Long` link:http://www.datanucleus.org:15080/products/accessplatform_5_2/jdo/mapping.html#_primitive_and_java_lang_types[out-of-the-box], so no special annotations are required.
+
+[source,java]
+----
+include::WrapperLongJpa.java[tags=class]
+----
+<.> a no-arg constructor is introduced by JDO enhancer
+<.> required property as defined to JDO/DataNucleus.
++
+Apache Isis assumes properties are mandatory, so no additional annotation is required.
+<.> directly editable property as defined to Apache Isis
+<.> optional property as defined to Apache Isis
+<.> optional property as defined to JDO/DataNucleus
+
+
+
+include::../WrapperLongs-common.adoc[]
\ No newline at end of file
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/longs/jpa/WrapperLongJpa.java b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/longs/jpa/WrapperLongJpa.java
new file mode 100644
index 0000000..44e7d21
--- /dev/null
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/longs/jpa/WrapperLongJpa.java
@@ -0,0 +1,95 @@
+/*
+ *  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 demoapp.dom.types.javalang.longs.jpa;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EntityListeners;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import org.springframework.context.annotation.Profile;
+
+import org.apache.isis.applib.annotation.DomainObject;
+import org.apache.isis.applib.annotation.Editing;
+import org.apache.isis.applib.annotation.Optionality;
+import org.apache.isis.applib.annotation.Property;
+import org.apache.isis.applib.annotation.PropertyLayout;
+import org.apache.isis.applib.annotation.Title;
+import org.apache.isis.persistence.jpa.applib.integration.JpaEntityInjectionPointResolver;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import demoapp.dom.types.javalang.longs.persistence.WrapperLongEntity;
+
+@Profile("demo-jpa")
+//tag::class[]
+@Entity
+@Table(
+      schema = "demo",
+      name = "JavaLangStringJpa"
+)
+@EntityListeners(JpaEntityInjectionPointResolver.class)
+@DomainObject(
+      objectType = "demo.WrapperLongEntity"
+)
+@NoArgsConstructor
+public class WrapperLongJpa
+        extends WrapperLongEntity {
+
+//end::class[]
+    public WrapperLongJpa(Long initialValue) {
+        this.readOnlyProperty = initialValue;
+        this.readWriteProperty = initialValue;
+    }
+
+//tag::class[]
+    @Id
+    @GeneratedValue
+    private Long id;
+
+    @Title(prepend = "Long (wrapper) JDO entity: ")
+    @PropertyLayout(fieldSetId = "read-only-properties", sequence = "1")
+    @Column(nullable = false)                                                   // <.>
+    @Getter @Setter
+    private Long readOnlyProperty;
+
+    @Property(editing = Editing.ENABLED)                                        // <.>
+    @PropertyLayout(fieldSetId = "editable-properties", sequence = "1")
+    @Column(nullable = false)
+    @Getter @Setter
+    private Long readWriteProperty;
+
+    @Property(optionality = Optionality.OPTIONAL)                               // <.>
+    @PropertyLayout(fieldSetId = "optional-properties", sequence = "1")
+    @Column(nullable = true)                                                    // <.>
+    @Getter @Setter
+    private Long readOnlyOptionalProperty;
+
+    @Property(editing = Editing.ENABLED, optionality = Optionality.OPTIONAL)
+    @PropertyLayout(fieldSetId = "optional-properties", sequence = "2")
+    @Column(nullable = true)
+    @Getter @Setter
+    private Long readWriteOptionalProperty;
+
+}
+//end::class[]
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/DemoModuleJpa.java b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/longs/jpa/WrapperLongJpaEntities.java
similarity index 66%
copy from examples/demo/domain/src/main/java/demoapp/dom/DemoModuleJpa.java
copy to examples/demo/domain/src/main/java/demoapp/dom/types/javalang/longs/jpa/WrapperLongJpaEntities.java
index f2a9c94..563a699 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/DemoModuleJpa.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/longs/jpa/WrapperLongJpaEntities.java
@@ -16,22 +16,25 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package demoapp.dom;
+package demoapp.dom.types.javalang.longs.jpa;
 
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Import;
 import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Service;
 
-import org.apache.isis.extensions.commandlog.jpa.IsisModuleExtCommandLogJpa;
-import org.apache.isis.persistence.jpa.eclipselink.IsisModuleJpaEclipselink;
+import demoapp.dom._infra.values.ValueHolderRepository;
 
-@Configuration
 @Profile("demo-jpa")
-@Import({
-    DemoModuleCommon.class,
-    IsisModuleJpaEclipselink.class,
-    IsisModuleExtCommandLogJpa.class,
-})
-public class DemoModuleJpa {
+@Service
+public class WrapperLongJpaEntities
+extends ValueHolderRepository<Long, WrapperLongJpa> {
+
+    protected WrapperLongJpaEntities() {
+        super(WrapperLongJpa.class);
+    }
+
+    @Override
+    protected WrapperLongJpa newDetachedEntity(Long value) {
+        return new WrapperLongJpa(value);
+    }
 
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/shorts/WrapperShorts.java b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/shorts/WrapperShorts.java
index 4c0cb62..a0807c1 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/shorts/WrapperShorts.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/shorts/WrapperShorts.java
@@ -36,18 +36,16 @@ import org.apache.isis.applib.annotation.Nature;
 import org.apache.isis.applib.annotation.PromptStyle;
 import org.apache.isis.applib.annotation.SemanticsOf;
 
-import lombok.extern.log4j.Log4j2;
-
 import demoapp.dom._infra.asciidocdesc.HasAsciiDocDescription;
-import demoapp.dom.types.javalang.shorts.jdo.WrapperShortJdo;
-import demoapp.dom.types.javalang.shorts.jdo.WrapperShortJdoEntities;
+import demoapp.dom._infra.values.ValueHolderRepository;
+import demoapp.dom.types.javalang.shorts.persistence.WrapperShortEntity;
 import demoapp.dom.types.javalang.shorts.vm.WrapperShortVm;
 
 @XmlRootElement(name = "Demo")
 @XmlType
 @XmlAccessorType(XmlAccessType.FIELD)
 @DomainObject(nature=Nature.VIEW_MODEL, objectType = "demo.WrapperShorts", editing=Editing.ENABLED)
-@Log4j2
+//@Log4j2
 public class WrapperShorts implements HasAsciiDocDescription {
 
     public String title() {
@@ -64,13 +62,13 @@ public class WrapperShorts implements HasAsciiDocDescription {
     }
 
     @Collection
-    public List<WrapperShortJdo> getEntities() {
+    public List<? extends WrapperShortEntity> getEntities() {
         return entities.all();
     }
 
     @Inject
     @XmlTransient
-    WrapperShortJdoEntities entities;
+    ValueHolderRepository<Short, ? extends WrapperShortEntity> entities;
 
 
 }
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/shorts/jpa/WrapperShortJpa-description.adoc b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/shorts/jpa/WrapperShortJpa-description.adoc
new file mode 100644
index 0000000..bcb893d
--- /dev/null
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/shorts/jpa/WrapperShortJpa-description.adoc
@@ -0,0 +1,23 @@
+: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 [...]
+
+[WARNING]
+==== 
+TODO this yet is just a copy from JDO
+====
+
+JDO supports `Short` link:http://www.datanucleus.org:15080/products/accessplatform_5_2/jdo/mapping.html#_primitive_and_java_lang_types[out-of-the-box], so no special annotations are required.
+
+[source,java]
+----
+include::WrapperShortJpa.java[tags=class]
+----
+<.> a no-arg constructor is introduced by JDO enhancer
+<.> required property as defined to JDO/DataNucleus.
++
+Apache Isis assumes properties are mandatory, so no additional annotation is required.
+<.> directly editable property as defined to Apache Isis
+<.> optional property as defined to Apache Isis
+<.> optional property as defined to JDO/DataNucleus
+
+
+include::../WrapperShorts-common.adoc[]
\ No newline at end of file
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/shorts/jpa/WrapperShortJpa.java b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/shorts/jpa/WrapperShortJpa.java
new file mode 100644
index 0000000..a4e9706
--- /dev/null
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/shorts/jpa/WrapperShortJpa.java
@@ -0,0 +1,95 @@
+/*
+ *  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 demoapp.dom.types.javalang.shorts.jpa;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EntityListeners;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import org.springframework.context.annotation.Profile;
+
+import org.apache.isis.applib.annotation.DomainObject;
+import org.apache.isis.applib.annotation.Editing;
+import org.apache.isis.applib.annotation.Optionality;
+import org.apache.isis.applib.annotation.Property;
+import org.apache.isis.applib.annotation.PropertyLayout;
+import org.apache.isis.applib.annotation.Title;
+import org.apache.isis.persistence.jpa.applib.integration.JpaEntityInjectionPointResolver;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+import demoapp.dom.types.javalang.shorts.persistence.WrapperShortEntity;
+
+@Profile("demo-jpa")
+//tag::class[]
+@Entity
+@Table(
+      schema = "demo",
+      name = "JavaLangStringJpa"
+)
+@EntityListeners(JpaEntityInjectionPointResolver.class)
+@DomainObject(
+      objectType = "demo.WrapperShortEntity"
+)
+@NoArgsConstructor
+public class WrapperShortJpa
+        extends WrapperShortEntity {
+
+//end::class[]
+    public WrapperShortJpa(Short initialValue) {
+        this.readOnlyProperty = initialValue;
+        this.readWriteProperty = initialValue;
+    }
+
+//tag::class[]
+    @Id
+    @GeneratedValue
+    private Long id;
+
+    @Title(prepend = "Short (wrapper) JDO entity: ")
+    @PropertyLayout(fieldSetId = "read-only-properties", sequence = "1")
+    @Column(nullable = false)                                                   // <.>
+    @Getter @Setter
+    private Short readOnlyProperty;
+
+    @Property(editing = Editing.ENABLED)                                        // <.>
+    @PropertyLayout(fieldSetId = "editable-properties", sequence = "1")
+    @Column(nullable = false)
+    @Getter @Setter
+    private Short readWriteProperty;
+
+    @Property(optionality = Optionality.OPTIONAL)                               // <.>
+    @PropertyLayout(fieldSetId = "optional-properties", sequence = "1")
+    @Column(nullable = true)                                                    // <.>
+    @Getter @Setter
+    private Short readOnlyOptionalProperty;
+
+    @Property(editing = Editing.ENABLED, optionality = Optionality.OPTIONAL)
+    @PropertyLayout(fieldSetId = "optional-properties", sequence = "2")
+    @Column(nullable = true)
+    @Getter @Setter
+    private Short readWriteOptionalProperty;
+
+}
+//end::class[]
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/DemoModuleJpa.java b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/shorts/jpa/WrapperShortJpaEntities.java
similarity index 66%
copy from examples/demo/domain/src/main/java/demoapp/dom/DemoModuleJpa.java
copy to examples/demo/domain/src/main/java/demoapp/dom/types/javalang/shorts/jpa/WrapperShortJpaEntities.java
index f2a9c94..ba684c7 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/DemoModuleJpa.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/types/javalang/shorts/jpa/WrapperShortJpaEntities.java
@@ -16,22 +16,25 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package demoapp.dom;
+package demoapp.dom.types.javalang.shorts.jpa;
 
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Import;
 import org.springframework.context.annotation.Profile;
+import org.springframework.stereotype.Service;
 
-import org.apache.isis.extensions.commandlog.jpa.IsisModuleExtCommandLogJpa;
-import org.apache.isis.persistence.jpa.eclipselink.IsisModuleJpaEclipselink;
+import demoapp.dom._infra.values.ValueHolderRepository;
 
-@Configuration
 @Profile("demo-jpa")
-@Import({
-    DemoModuleCommon.class,
-    IsisModuleJpaEclipselink.class,
-    IsisModuleExtCommandLogJpa.class,
-})
-public class DemoModuleJpa {
+@Service
+public class WrapperShortJpaEntities
+extends ValueHolderRepository<Short, WrapperShortJpa> {
+
+    protected WrapperShortJpaEntities() {
+        super(WrapperShortJpa.class);
+    }
+
+    @Override
+    protected WrapperShortJpa newDetachedEntity(Short value) {
+        return new WrapperShortJpa(value);
+    }
 
 }
diff --git a/examples/demo/web/src/main/java/demoapp/web/DemoAppManifestJpa.java b/examples/demo/web/src/main/java/demoapp/web/DemoAppManifestJpa.java
index 27e7cfe..bbfbf30 100644
--- a/examples/demo/web/src/main/java/demoapp/web/DemoAppManifestJpa.java
+++ b/examples/demo/web/src/main/java/demoapp/web/DemoAppManifestJpa.java
@@ -18,14 +18,12 @@
  */
 package demoapp.web;
 
-import org.springframework.boot.autoconfigure.domain.EntityScan;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Import;
 
 import org.apache.isis.extensions.secman.jpa.IsisModuleExtSecmanPersistenceJpa;
 
 import demoapp.dom.DemoModuleJpa;
-import demoapp.dom.types.javalang.strings.jpa.JavaLangStringJpa;
 
 /**
  * Makes the integral parts of the 'demo' web application.
@@ -39,9 +37,6 @@ import demoapp.dom.types.javalang.strings.jpa.JavaLangStringJpa;
     IsisModuleExtSecmanPersistenceJpa.class,
 
 })
-@EntityScan(basePackageClasses = {
-        JavaLangStringJpa.class,
-})
 public class DemoAppManifestJpa {
 
 }