You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2016/06/17 14:57:55 UTC

isis git commit: ISIS-1335: adds docs for datanucleus-java8

Repository: isis
Updated Branches:
  refs/heads/master 3b7a74c55 -> bb51c5072


ISIS-1335: adds docs for datanucleus-java8

Within the btb guide.


Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/bb51c507
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/bb51c507
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/bb51c507

Branch: refs/heads/master
Commit: bb51c507293ecc69d5dde4311d5fbbef4d963fae
Parents: 3b7a74c
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Fri Jun 17 15:50:53 2016 +0100
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Fri Jun 17 15:56:36 2016 +0100

----------------------------------------------------------------------
 .../asciidoc/guides/_ugbtb_datanucleus.adoc     | 24 ++++++++
 .../guides/_ugbtb_datanucleus_java8.adoc        | 29 +++++++++
 ..._datanucleus_overriding-jdo-annotations.adoc | 64 ++++++++++++++++++++
 .../guides/_ugbtb_other-techniques.adoc         |  1 -
 .../_ugbtb_other-techniques_multi-tenancy.adoc  |  7 ++-
 ...r-techniques_overriding-jdo-annotations.adoc | 64 --------------------
 ...placing-default-service-implementations.adoc |  2 +-
 ...ther-techniques_transactions-and-errors.adoc | 63 ++++++++++++++++---
 .../src/main/asciidoc/guides/ugbtb.adoc         |  1 +
 9 files changed, 179 insertions(+), 76 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/bb51c507/adocs/documentation/src/main/asciidoc/guides/_ugbtb_datanucleus.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_datanucleus.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_datanucleus.adoc
new file mode 100644
index 0000000..306a41f
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_datanucleus.adoc
@@ -0,0 +1,24 @@
+[[_ugbtb_datanucleus]]
+= DataNucleus
+: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 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.
+:_basedir: ../
+:_imagesdir: images/
+
+
+
+Apache Isis uses link:http://datanucleus.org[DataNucleus] to handle persistence of domain entities, using the JDO API.
+This chapter contains some guidance on working with DataNucleus in the context of Apache Isis applications.
+
+[NOTE]
+====
+DataNucleus as a product also supports the JPA API; Apache Isis is likely to also support JPA in the future.
+====
+
+
+include::_ugbtb_datanucleus_overriding-jdo-annotations.adoc[leveloffset=+1]
+include::_ugbtb_datanucleus_java8.adoc[leveloffset=+1]
+
+
+
+
+

http://git-wip-us.apache.org/repos/asf/isis/blob/bb51c507/adocs/documentation/src/main/asciidoc/guides/_ugbtb_datanucleus_java8.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_datanucleus_java8.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_datanucleus_java8.adoc
new file mode 100644
index 0000000..495d69f
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_datanucleus_java8.adoc
@@ -0,0 +1,29 @@
+[[_ugbtb_datanucleus_java8]]
+= Java8
+: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 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.
+:_basedir: ../
+:_imagesdir: images/
+
+
+
+DataNucleus 4.x supports Java 7, but can also be used with Java 8, eg for streams support against collections managed
+by DataNucleus.
+
+Just include within `<dependencies>` of your `dom` module's `pom.xml`:
+
+[source,xml]
+----
+<dependency>
+    <groupId>org.datanucleus</groupId>
+    <artifactId>datanucleus-java8</artifactId>
+    <version>4.2.0-release</version>t
+</dependency>
+----
+
+[NOTE]
+====
+The DataNucleus website includes a link:http://www.datanucleus.org/products/accessplatform/compatibility.html[page]
+listing version compatibility of these extensions vis-a-vis the core DataNucleus platform.
+====
+
+

http://git-wip-us.apache.org/repos/asf/isis/blob/bb51c507/adocs/documentation/src/main/asciidoc/guides/_ugbtb_datanucleus_overriding-jdo-annotations.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_datanucleus_overriding-jdo-annotations.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_datanucleus_overriding-jdo-annotations.adoc
new file mode 100644
index 0000000..2a8186a
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_datanucleus_overriding-jdo-annotations.adoc
@@ -0,0 +1,64 @@
+[[_ugbtb_datanucleus_overriding-jdo-annotations]]
+= Overriding JDO Annotations
+: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 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.
+:_basedir: ../
+:_imagesdir: images/
+
+
+
+The JDO Objectstore (or rather, the underlying DataNucleus implementation) builds its own persistence metamodel by reading both annotations on the class and also by searching for metadata in XML files. The metadata in the XML files takes precedence over the annotations, and so can be used to override metadata that is "hard-coded" in annotations.
+
+For example, as of 1.9.0 the various http://www.isisaddons.org[Isis addons] modules (not ASF) use schemas for each entity. For example, the `AuditEntry` entity in the http://github.com/isisaddons/isis-module-audit[audit module] is annotated as:
+
+[source,java]
+----
+@javax.jdo.annotations.PersistenceCapable(
+        identityType=IdentityType.DATASTORE,
+        schema = "IsisAddonsAudit",
+        table="AuditEntry")
+public class AuditEntry {
+    ...
+}
+----
+
+This will map the `AuditEntry` class to a table `&quot;IsisAddonsAudit&quot;.&quot;AuditEntry&quot;`; that is using a custom schema to own the object.
+
+Suppose though that for whatever reason we didn't want to use a custom schema but would rather use the default. We can override the above annotation using a `package.jdo` file, for example:
+
+[source,xml]
+----
+<?xml version="1.0" encoding="UTF-8" ?>
+<jdo xmlns="http://xmlns.jcp.org/xml/ns/jdo/jdo"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/jdo/jdo
+        http://xmlns.jcp.org/xml/ns/jdo/jdo_3_0.xsd" version="3.0">
+    <package name="org.isisaddons.module.audit.dom">
+        <class name="AuditEntry" schema="PUBLIC" table="IsisAddonsAuditEntry">
+        </class>
+    </package>
+</jdo>
+----
+
+This file should be placed can be placed in `src/main/java/META-INF` within your application's `dom` module.
+
+[TIP]
+====
+You can use a mixin action on xref:rgcms.adoc#_rgcms_classes_mixins_Persistable[`Persistable`] mixin
+to download the JDO class metadata in XML form.
+====
+
+
+[NOTE]
+====
+* The same approach should work for any other JDO metadata, but some experimentation might be required.+
++
+For example, in writing up the above example we found that writing `schema=&quot;&quot;` (in an attempt to say, "use the default schema for this table") actually caused the original annotation value to be used instead.
+
+* Forcing the schema to "PUBLIC" (as in the above example) works, but it isn't ideal because the name "PUBLIC" is not vendor-neutral (it works for HSQLDB, but MS SQL Server uses "dbo" as its default).
+
+* As of 1.9.0 Apache Isis will automatically (attempt) to create the owning schema for a given table if it does not exist. This behaviour can be customized, as described in the section on xref:_ugbtb_decoupling_db-schemas[using modules].
+
+* You may need to override the entire class metadata rather than individual elements; the mixin mentioned above can help here.
+====
+
+

http://git-wip-us.apache.org/repos/asf/isis/blob/bb51c507/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques.adoc
index d03bf12..feb075d 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques.adoc
@@ -9,7 +9,6 @@
 This chapter pulls together a number of more advanced techniques that we've discovered and developed while building our own Isis applications.
 
 
-include::_ugbtb_other-techniques_overriding-jdo-annotations.adoc[leveloffset=+1]
 include::_ugbtb_other-techniques_mapping-rdbms-views.adoc[leveloffset=+1]
 include::_ugbtb_other-techniques_transactions-and-errors.adoc[leveloffset=+1]
 include::_ugbtb_other-techniques_multi-tenancy.adoc[leveloffset=+1]

http://git-wip-us.apache.org/repos/asf/isis/blob/bb51c507/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_multi-tenancy.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_multi-tenancy.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_multi-tenancy.adoc
index 6bc2936..270e98f 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_multi-tenancy.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_multi-tenancy.adoc
@@ -4,5 +4,10 @@
 :_basedir: ../
 :_imagesdir: images/
 
-NOTE: TODO - as supported by (non-ASF) http://github.com/isisaddons/isis-module-security[Isis addons' security] module.
+
+Of the various Isis Addons, the https://github.com/isisaddons/isis-module-security[security module] has the most features. One significant feature is the ability to associate users and objects with a "tenancy".
+
+
+For more details, see the https://github.com/isisaddons/isis-module-security[security module] README.
+
 

http://git-wip-us.apache.org/repos/asf/isis/blob/bb51c507/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_overriding-jdo-annotations.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_overriding-jdo-annotations.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_overriding-jdo-annotations.adoc
deleted file mode 100644
index 7f23e52..0000000
--- a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_overriding-jdo-annotations.adoc
+++ /dev/null
@@ -1,64 +0,0 @@
-[[_ugbtb_other-techniques_overriding-jdo-annotations]]
-= Overriding JDO Annotations
-: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 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.
-:_basedir: ../
-:_imagesdir: images/
-
-
-
-The JDO Objectstore (or rather, the underlying DataNucleus implementation) builds its own persistence metamodel by reading both annotations on the class and also by searching for metadata in XML files. The metadata in the XML files takes precedence over the annotations, and so can be used to override metadata that is "hard-coded" in annotations.
-
-For example, as of 1.9.0 the various http://www.isisaddons.org[Isis addons] modules (not ASF) use schemas for each entity. For example, the `AuditEntry` entity in the http://github.com/isisaddons/isis-module-audit[audit module] is annotated as:
-
-[source,java]
-----
-@javax.jdo.annotations.PersistenceCapable(
-        identityType=IdentityType.DATASTORE,
-        schema = "IsisAddonsAudit",
-        table="AuditEntry")
-public class AuditEntry {
-    ...
-}
-----
-
-This will map the `AuditEntry` class to a table `&quot;IsisAddonsAudit&quot;.&quot;AuditEntry&quot;`; that is using a custom schema to own the object.
-
-Suppose though that for whatever reason we didn't want to use a custom schema but would rather use the default. We can override the above annotation using a `package.jdo` file, for example:
-
-[source,xml]
-----
-<?xml version="1.0" encoding="UTF-8" ?>
-<jdo xmlns="http://xmlns.jcp.org/xml/ns/jdo/jdo"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/jdo/jdo
-        http://xmlns.jcp.org/xml/ns/jdo/jdo_3_0.xsd" version="3.0">
-    <package name="org.isisaddons.module.audit.dom">
-        <class name="AuditEntry" schema="PUBLIC" table="IsisAddonsAuditEntry">
-        </class>
-    </package>
-</jdo>
-----
-
-This file should be placed can be placed in `src/main/java/META-INF` within your application's `dom` module.
-
-[TIP]
-====
-You can use a mixin action on xref:rgcms.adoc#_rgcms_classes_mixins_Persistable[`Persistable`] mixin
-to download the JDO class metadata in XML form.
-====
-
-
-[NOTE]
-====
-* The same approach should work for any other JDO metadata, but some experimentation might be required.+
-+
-For example, in writing up the above example we found that writing `schema=&quot;&quot;` (in an attempt to say, "use the default schema for this table") actually caused the original annotation value to be used instead.
-
-* Forcing the schema to "PUBLIC" (as in the above example) works, but it isn't ideal because the name "PUBLIC" is not vendor-neutral (it works for HSQLDB, but MS SQL Server uses "dbo" as its default).
-
-* As of 1.9.0 Apache Isis will automatically (attempt) to create the owning schema for a given table if it does not exist. This behaviour can be customized, as described in the section on xref:_ugbtb_decoupling_db-schemas[using modules].
-
-* You may need to override the entire class metadata rather than individual elements; the mixin mentioned above can help here.
-====
-
-

http://git-wip-us.apache.org/repos/asf/isis/blob/bb51c507/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_replacing-default-service-implementations.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_replacing-default-service-implementations.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_replacing-default-service-implementations.adoc
index 50ff20b..864d8ca 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_replacing-default-service-implementations.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_replacing-default-service-implementations.adoc
@@ -1,5 +1,5 @@
 [[_ugbtb_other-techniques_replacing-default-service-implementations]]
-= Replacing Service Implns
+= Overriding Default Service Implns
 :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 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.
 :_basedir: ../
 :_imagesdir: images/

http://git-wip-us.apache.org/repos/asf/isis/blob/bb51c507/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_transactions-and-errors.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_transactions-and-errors.adoc b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_transactions-and-errors.adoc
index 19eb19e..8920439 100644
--- a/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_transactions-and-errors.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/_ugbtb_other-techniques_transactions-and-errors.adoc
@@ -4,30 +4,75 @@
 :_basedir: ../
 :_imagesdir: images/
 
-In Apache Isis, every action invocation (in fact, every interaction) is automatically wrapped in a transaction, and any repository query automatically does a flush.
+In Apache Isis, every interaction (action invocation or property edit) is automatically wrapped in a transaction,
+and any repository query automatically does a flush before hand.
 
-What that means is that there's no need to explicitly start or commit transactions in Apache Isis; this will be done for you. Indeed, if you do try to manage transactions (eg by reaching into the JDO `PersistenceManager` exposed by the xref:rgsvc.adoc#_rgsvc_api_IsisJdoSupport[IsisJdoSupport] domain service, then you are likely to confuse Isis and get a stack trace for your trouble.
+What that means is that there's no need to explicitly start or commit transactions in Apache Isis; this will be done
+for you. Indeed, if you do try to manage transactions (eg by reaching into the JDO `PersistenceManager` exposed by the
+xref:rgsvc.adoc#_rgsvc_api_IsisJdoSupport[IsisJdoSupport] domain service, then you are likely to confuse the
+framework and get a stack trace for your trouble.
 
+However, you can complete a given transaction and start a new one.  This is sometimes useful if writing a fixture
+script which is going to perform some sort of bulk migration of data from an old system.  For this use case, use the
+xref:rgsvc.adoc#_rgsvc_api_TransactionService[`TransactionService`].
 
+For example:
 
+[source,java]
+----
+public class SomeLongRunningFixtureScript extends FixtureScript
 
-== Aborting Transactions
+    protected void execute(final ExecutionContext executionContext) {
+        // do some work
+        transactionService.nextTransaction();
+        // do some work
+        transactionService.nextTransaction();
+        // do yet more work
+    }
 
-If you want to abort Apache Isis' transaction, this can be done by throwing `RecoverableException` (or any subclass, eg `ApplicationException`). The transaction will be aborted, and the exception message will be displayed to the user.
+    @javax.inject.Inject
+    TransactionService transactionService;
+}
+----
 
-If you throw any other exception (ie not a subclass of `RecoverableException`), then the users will see an error page (if Wicket viewer) or a 500 (if Restful Objects viewer).
+You get the idea.
 
 
+== Raise message/errors to users
 
+The framework provides the xref:rgsvc.adoc#_rgsvc_api_MessageService[`MessageService`] as a means to return an out-of-band
+message to the end-user.  In the xref:ugvw.adoc#[Wicket viewer] these are shown as "toast" pop-ups; the
+xref:ugvro.adoc#[Restful Objects viewer] returns an HTTP header.
 
+The `UserService` provides three APIs, for different:
+
+* `informUser()` - an informational message.  In the Wicket viewer these are short-lived pop-ups that disappear after a short time.
+* `warnUser()` - a warning.  In the Wicket viewer these do not auto-close; they must be acknowledged.
+* `raiseError()` - an error.  In the Wicket viewer these do not auto-close; they must be acknowledged.
+
+Each pop-up has a different background colour indicating its severity.
+
+None of these messages/errors has any influence on the transaction; any changes to objects will be committed.
 
-== Raise message/errors to users
 
-NOTE: TODO - xref:rgsvc.adoc#_rgsvc_api_DomainObjectContainer_messages-api[`DomainObjectContainer`]
+== Aborting transactions
 
+If you want to abort Apache Isis' transaction, this can be done by throwing an exception.  The exception message
+is displayed to the user on the error page (if xref:ugvw.adoc#[Wicket viewer]) or a 500 status error code (if the
+xref:ugvro.adoc#[Restful Objects] viewer).
 
+If the exception thrown is because of an unexpected error (eg a `NullPointerException` in the domain app itself), then
+the error page will include a stack trace.  If however you want to indicate that the exception is in some sense
+"expected", then throw a `RecoverableException` (or any subclass, eg `ApplicationException`); the stack trace will then
+be suppressed from the error page.
 
-== Exception Recognizers
+Another way in which exceptions might be considered "expected" could be as the result of attempting to persist an
+object which then violates some type of database constraint.  Even if the domain application checks beforehand, it
+could be that another user operating on the object at the same moment of time might result in the conflict.
 
-NOTE: TODO - xref:rgsvc.adoc#_rgsvc_spi_ExceptionRecognizer[`ExceptionRecognizer`] service
+To handle this the xref:rgsvc.adoc#_rgsvc_spi_ExceptionRecognizer[`ExceptionRecognizer`] SPI can be used.  The
+framework provides a number of implementations out-of-the-box; whenever an exception is thrown it is passed to each
+known recognizer implementation to see if it recognizes the exception and can return a user-meaningful error message.
+For example, `ExceptionRecognizerForSQLIntegrityConstraintViolationUniqueOrIndexException` checks if the
+exception inherits from `java.sql.SQLIntegrityConstraintViolationException`, and if so, constructs a suitable message.
 

http://git-wip-us.apache.org/repos/asf/isis/blob/bb51c507/adocs/documentation/src/main/asciidoc/guides/ugbtb.adoc
----------------------------------------------------------------------
diff --git a/adocs/documentation/src/main/asciidoc/guides/ugbtb.adoc b/adocs/documentation/src/main/asciidoc/guides/ugbtb.adoc
index 4b5b78a..5095118 100644
--- a/adocs/documentation/src/main/asciidoc/guides/ugbtb.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/ugbtb.adoc
@@ -47,6 +47,7 @@ include::_ugbtb_view-models.adoc[leveloffset=+1]
 include::_ugbtb_decoupling.adoc[leveloffset=+1]
 include::_ugbtb_i18n.adoc[leveloffset=+1]
 include::_ugbtb_headless-access.adoc[leveloffset=+1]
+include::_ugbtb_datanucleus.adoc[leveloffset=+1]
 include::_ugbtb_other-techniques.adoc[leveloffset=+1]
 include::_ugbtb_programming-model.adoc[leveloffset=+1]
 include::_ugbtb_deployment.adoc[leveloffset=+1]