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/01/13 11:36:29 UTC

[isis] branch master updated: ISIS-2033: consolidate IsisJdoSupport* into JdoSupportService

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 d9c3c55  ISIS-2033: consolidate IsisJdoSupport* into JdoSupportService
d9c3c55 is described below

commit d9c3c55651a67a56efd7a5270df527546209e434
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Jan 13 12:36:15 2021 +0100

    ISIS-2033: consolidate IsisJdoSupport* into JdoSupportService
---
 .../commandlog/impl/jdo/CommandJdoRepository.java  |   6 +-
 .../isis/legacy/applib/DomainObjectContainer.java  |   8 +-
 .../jdo/applib/integration/JdoSupportService.java  | 146 +++++++++++++++++++++
 .../jdo/applib/services/IsisJdoSupport.java        |  93 -------------
 .../jdo/applib/services/IsisJdoSupport_v3_2.java   | 129 ------------------
 .../mixins/Persistable_downloadJdoMetadata.java    |   4 +-
 .../jdo/integration/IsisModuleJdoIntegration.java  |   4 +-
 ...pportDN5.java => JdoSupportServiceDefault.java} |  33 +++--
 .../metamodel/facets/entity/JdoEntityFacet.java    |   2 +-
 .../jdo/metamodel/menu/JdoMetamodelMenu.java       |   4 +-
 ...sactionAwarePersistenceManagerFactoryProxy.java |   8 +-
 .../ExcelDemoToDoItem_tearDown2.java               |   8 +-
 .../applib/teardown/TeardownFixtureAbstract.java   |  16 +--
 13 files changed, 196 insertions(+), 265 deletions(-)

diff --git a/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdoRepository.java b/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdoRepository.java
index 7f1bd44..f0e005e 100644
--- a/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdoRepository.java
+++ b/extensions/core/command-log/impl/src/main/java/org/apache/isis/extensions/commandlog/impl/jdo/CommandJdoRepository.java
@@ -46,7 +46,7 @@ import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.services.iactn.InteractionContext;
 import org.apache.isis.applib.services.repository.RepositoryService;
 import org.apache.isis.applib.util.schema.CommandDtoUtils;
-import org.apache.isis.persistence.jdo.applib.services.IsisJdoSupport_v3_2;
+import org.apache.isis.persistence.jdo.applib.integration.JdoSupportService;
 import org.apache.isis.schema.cmd.v2.CommandDto;
 import org.apache.isis.schema.cmd.v2.CommandsDto;
 import org.apache.isis.schema.cmd.v2.MapDto;
@@ -70,7 +70,7 @@ public class CommandJdoRepository {
 
     @Inject final Provider<InteractionContext> interactionContextProvider;
     @Inject final RepositoryService repositoryService;
-    @Inject final IsisJdoSupport_v3_2 isisJdoSupport;
+    @Inject final JdoSupportService jdoSupport;
 
     public List<CommandJdo> findByFromAndTo(
             @Nullable final LocalDate from,
@@ -235,7 +235,7 @@ public class CommandJdoRepository {
 
 
     private CommandJdo findByUniqueIdElseNull(final UUID uniqueId) {
-        val tsq = isisJdoSupport.newTypesafeQuery(CommandJdo.class);
+        val tsq = jdoSupport.newTypesafeQuery(CommandJdo.class);
         val cand = QCommandJdo.candidate();
         val q = tsq.filter(
                 cand.uniqueIdStr.eq(tsq.parameter("uniqueIdStr", String.class))
diff --git a/legacy/extensions/core/applib/src/main/java/org/apache/isis/legacy/applib/DomainObjectContainer.java b/legacy/extensions/core/applib/src/main/java/org/apache/isis/legacy/applib/DomainObjectContainer.java
index ced7d26..335789f 100644
--- a/legacy/extensions/core/applib/src/main/java/org/apache/isis/legacy/applib/DomainObjectContainer.java
+++ b/legacy/extensions/core/applib/src/main/java/org/apache/isis/legacy/applib/DomainObjectContainer.java
@@ -36,7 +36,6 @@ import org.apache.isis.applib.ViewModel;
 import org.apache.isis.applib.annotation.OrderPrecedence;
 import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.query.Query;
-import org.apache.isis.applib.services.user.UserMemento;
 import org.apache.isis.applib.services.factory.FactoryService;
 import org.apache.isis.applib.services.i18n.TranslatableString;
 import org.apache.isis.applib.services.inject.ServiceInjector;
@@ -45,12 +44,13 @@ import org.apache.isis.applib.services.metamodel.MetaModelService;
 import org.apache.isis.applib.services.registry.ServiceRegistry;
 import org.apache.isis.applib.services.repository.RepositoryService;
 import org.apache.isis.applib.services.title.TitleService;
+import org.apache.isis.applib.services.user.UserMemento;
 import org.apache.isis.applib.services.user.UserService;
 import org.apache.isis.applib.services.xactn.TransactionService;
 import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.core.config.IsisConfiguration;
 import org.apache.isis.legacy.applib.filter.Filter;
-import org.apache.isis.persistence.jdo.applib.services.IsisJdoSupport;
+import org.apache.isis.persistence.jdo.applib.integration.JdoSupportService;
 
 import lombok.NonNull;
 import lombok.SneakyThrows;
@@ -68,7 +68,7 @@ public class DomainObjectContainer {
 	
 	@Inject private RepositoryService repositoryService;
 	@Inject private MetaModelService metaModelService;
-	@Inject private IsisJdoSupport isisJdoSupport;
+	@Inject private JdoSupportService jdoSupport;
 	@Inject private FactoryService factoryService;
 	@Inject private TitleService titleService;
 	@Inject private TransactionService transactionService;
@@ -115,7 +115,7 @@ public class DomainObjectContainer {
     @Programmatic
     @Deprecated
     public void resolve(Object domainObject) {
-    	isisJdoSupport.refresh(domainObject);
+        jdoSupport.refresh(domainObject);
     }
 
     /**
diff --git a/persistence/jdo/applib/src/main/java/org/apache/isis/persistence/jdo/applib/integration/JdoSupportService.java b/persistence/jdo/applib/src/main/java/org/apache/isis/persistence/jdo/applib/integration/JdoSupportService.java
index b280e36..b0866bb 100644
--- a/persistence/jdo/applib/src/main/java/org/apache/isis/persistence/jdo/applib/integration/JdoSupportService.java
+++ b/persistence/jdo/applib/src/main/java/org/apache/isis/persistence/jdo/applib/integration/JdoSupportService.java
@@ -18,13 +18,159 @@
  */
 package org.apache.isis.persistence.jdo.applib.integration;
 
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import javax.annotation.Nullable;
+import javax.jdo.JDOQLTypedQuery;
 import javax.jdo.PersistenceManager;
 import javax.jdo.PersistenceManagerFactory;
+import javax.jdo.Query;
+import javax.jdo.query.BooleanExpression;
+
+import org.datanucleus.store.rdbms.RDBMSPropertyNames;
 
+/**
+ * Primarily provides access to the current thread's {@link PersistenceManagerFactory} and 
+ * hence also the current thread's {@link PersistenceManager}. 
+ *  
+ * @since 2.0 {@index}
+ * 
+ * @apiNote While ideally should be independent of vendor specifics, yet depends on DataNucleus RDBMS. 
+ */
 public interface JdoSupportService {
+    
+    // -- INTERFACE
 
     PersistenceManagerFactory getPersistenceManagerFactory();
     
+    /**
+     * Force a reload (corresponding to the JDO <tt>PersistenceManager</tt>'s <tt>refresh()</tt> method)
+     * of a domain objects.
+     *
+     * <p>
+     * In fact, this may just reset the lazy-load state of the domain object, but the effect is the same:
+     * to cause the object's state to be reloaded from the database.
+     *
+     * <p>
+     * The particular example that led to this method being added was a 1:m bidirectional relationship,
+     * analogous to <tt>Customer <-> * Order</tt>.  Persisting the child <tt>Order</tt> object did not cause
+     * the parent <tt>Customer</tt>'s collection of orders to be updated.  In fact, JDO does not make any
+     * such guarantee to do so.  Options are therefore either to maintain the collection in code, or to
+     * refresh the parent.
+     */
+    <T> T refresh(T domainObject);
+
+    void ensureLoaded(Collection<?> collectionOfDomainObjects);
+
+    List<Map<String, Object>> executeSql(String sql);
+
+    Integer executeUpdate(String sql);
+
+    /**
+     * Force the deletion of all instances of the specified class.
+     *
+     * <p>
+     * Note: this is intended primarily for testing purposes, eg clearing existing data as part of
+     * installing fixtures.  It will generate a <tt>SQL DELETE</tt> for each instance.  To perform
+     * a bulk deletion with a single <tt>SQL DELETE</tt>, use {@link #executeUpdate(String)}.
+     *
+     * <p>
+     * Implementation note: It can occasionally be the case that Isis' internal adapter for the domain object is
+     * still in memory.  JDO/DataNucleus seems to bump up the version of the object prior to its deletion,
+     * which under normal circumstances would cause Isis to throw a concurrency exception.  Therefore
+     * To prevent this from happening (ie to <i>force</i> the deletion of all instances), concurrency checking
+     * is temporarily disabled while this method is performed.
+     */
+    void deleteAll(Class<?>... pcClasses);
+    
+    // -- QUERIES
+    
+    /**
+     * To perform the most common use-case of executing a (type-safe) query against the specified class,
+     * filtering using the provided {@link BooleanExpression}, then automatically cloning the returned list
+     * and closing the query.
+     *
+     * <p>
+     *     Typical usage:
+     *     <pre>
+     *          final QToDoItem q = QToDoItem.candidate();
+     *          return executeQuery(ToDoItem.class,
+     *                              q.atPath.eq(atPath).and(
+     *                              q.description.indexOf(description).gt(0))
+     *                              );
+     *     </pre>
+     * </p>
+     */
+    <T> List<T> executeQuery(final Class<T> cls, @Nullable final BooleanExpression filter);
+
+    default <T> List<T> executeQuery(final Class<T> cls) {
+        return executeQuery(cls, null);
+    }
+
+    /**
+     * To perform a common use-case of executing a (type-safe) query against the specified class,
+     * filtering a unique match using the provided {@link BooleanExpression}, then returning
+     * the result and closing the query.
+     *
+     * <p>
+     *     Typical usage:
+     *     <pre>
+     *          final QToDoItem q = QToDoItem.candidate();
+     *          return executeQueryUnique(ToDoItem.class,
+     *                              q.atPath.eq(atPath).and(
+     *                              q.description.eq(description))
+     *                              );
+     *     </pre>
+     * </p>
+     */
+    <T> T executeQueryUnique(final Class<T> cls, @Nullable final BooleanExpression filter);
+
+    default <T> T executeQueryUnique(final Class<T> cls) {
+        return executeQueryUnique(cls, null);
+    }
+
+    /**
+     * To support the execution of type-safe queries using DataNucleus' lower-level APIs
+     * (eg for group by and so on).
+     *
+     * <p>
+     *     Responsibility for cloning any result sets and closing the query is the responsibility
+     *     of the caller.
+     * </p>
+     */
+    <T> JDOQLTypedQuery<T> newTypesafeQuery(Class<T> cls);
+
+    // -- UTILITY
+
+    /**
+     * Fetch Optimization
+     * <p>
+     * From <a href="http://www.datanucleus.org/products/accessplatform/jdo/query.html">DN-5.2</a> ...
+     * <p>
+     * For RDBMS any single-valued member will be fetched in the original SQL query, but with 
+     * multiple-valued members this is not supported. However what will happen is that any 
+     * collection/array field will be retrieved in a single SQL query for all candidate objects 
+     * (by default using an EXISTS subquery); this avoids the "N+1" problem, resulting in 1 original 
+     * SQL query plus 1 SQL query per collection member. Note that you can disable this by either 
+     * not putting multi-valued fields in the FetchPlan, or by setting the query extension 
+     * datanucleus.rdbms.query.multivaluedFetch to none (default is "exists" using the single SQL per field).
+     */
+    default void disableMultivaluedFetch(JDOQLTypedQuery<?> query) {
+        query.extension(RDBMSPropertyNames.PROPERTY_RDBMS_QUERY_MULTIVALUED_FETCH, "none");
+    }
+
+    /**
+     * Fetch Optimization
+     * @see {@link IsisJdoSupport_v3_2#disableMultivaluedFetch(JDOQLTypedQuery)}
+     * @param query
+     */
+    default void disableMultivaluedFetch(Query<?> query) {
+        query.addExtension(RDBMSPropertyNames.PROPERTY_RDBMS_QUERY_MULTIVALUED_FETCH, "none");
+    }
+    
+    
     // -- SHORTCUTS
     
     default PersistenceManager getPersistenceManager() {
diff --git a/persistence/jdo/applib/src/main/java/org/apache/isis/persistence/jdo/applib/services/IsisJdoSupport.java b/persistence/jdo/applib/src/main/java/org/apache/isis/persistence/jdo/applib/services/IsisJdoSupport.java
deleted file mode 100644
index 09a7f8f..0000000
--- a/persistence/jdo/applib/src/main/java/org/apache/isis/persistence/jdo/applib/services/IsisJdoSupport.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.persistence.jdo.applib.services;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-import javax.jdo.PersistenceManager;
-
-import org.apache.isis.applib.annotation.Programmatic;
-
-//import javax.jdo.JDOQLTypedQuery;
-//import javax.jdo.query.BooleanExpression;
-
-
-/**
- * Service that provides a number of workarounds when using JDO/DataNucleus.<br/><br/>
- *
- * 1.x to 2.x Migration Notes: JDO API version specific query methods have been removed.<br/>
- * Instead you may want to use IsisJdoSupport_v3_1 or IsisJdoSupport_v3_2 as provided by Isis'
- * core plugins for JDO.
- *
- */
-public interface IsisJdoSupport {
-
-    /**
-     * Force a reload (corresponding to the JDO <tt>PersistenceManager</tt>'s <tt>refresh()</tt> method)
-     * of a domain objects.
-     *
-     * <p>
-     * In fact, this may just reset the lazy-load state of the domain object, but the effect is the same:
-     * to cause the object's state to be reloaded from the database.
-     *
-     * <p>
-     * The particular example that led to this method being added was a 1:m bidirectional relationship,
-     * analogous to <tt>Customer <-> * Order</tt>.  Persisting the child <tt>Order</tt> object did not cause
-     * the parent <tt>Customer</tt>'s collection of orders to be updated.  In fact, JDO does not make any
-     * such guarantee to do so.  Options are therefore either to maintain the collection in code, or to
-     * refresh the parent.
-     */
-    @Programmatic
-    <T> T refresh(T domainObject);
-
-    @Programmatic
-    void ensureLoaded(Collection<?> collectionOfDomainObjects);
-
-    @Programmatic
-    PersistenceManager getPersistenceManager();
-
-    @Programmatic
-    List<Map<String, Object>> executeSql(String sql);
-
-    @Programmatic
-    Integer executeUpdate(String sql);
-
-    /**
-     * Force the deletion of all instances of the specified class.
-     *
-     * <p>
-     * Note: this is intended primarily for testing purposes, eg clearing existing data as part of
-     * installing fixtures.  It will generate a <tt>SQL DELETE</tt> for each instance.  To perform
-     * a bulk deletion with a single <tt>SQL DELETE</tt>, use {@link #executeUpdate(String)}.
-     *
-     * <p>
-     * Implementation note: It can occasionally be the case that Isis' internal adapter for the domain object is
-     * still in memory.  JDO/DataNucleus seems to bump up the version of the object prior to its deletion,
-     * which under normal circumstances would cause Isis to throw a concurrency exception.  Therefore
-     * To prevent this from happening (ie to <i>force</i> the deletion of all instances), concurrency checking
-     * is temporarily disabled while this method is performed.
-     */
-    @Programmatic
-    void deleteAll(Class<?>... pcClasses);
-
-
-}
diff --git a/persistence/jdo/applib/src/main/java/org/apache/isis/persistence/jdo/applib/services/IsisJdoSupport_v3_2.java b/persistence/jdo/applib/src/main/java/org/apache/isis/persistence/jdo/applib/services/IsisJdoSupport_v3_2.java
deleted file mode 100644
index 9009455..0000000
--- a/persistence/jdo/applib/src/main/java/org/apache/isis/persistence/jdo/applib/services/IsisJdoSupport_v3_2.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-
-package org.apache.isis.persistence.jdo.applib.services;
-
-import java.util.List;
-
-import javax.annotation.Nullable;
-import javax.jdo.JDOQLTypedQuery;
-import javax.jdo.Query;
-import javax.jdo.query.BooleanExpression;
-
-import org.datanucleus.store.rdbms.RDBMSPropertyNames;
-
-import org.apache.isis.applib.annotation.Programmatic;
-
-/**
- * Service that provide a number of workarounds when using JDO/DataNucleus.
- */
-public interface IsisJdoSupport_v3_2 extends IsisJdoSupport
-{
-
-    /**
-     * To perform the most common use-case of executing a (type-safe) query against the specified class,
-     * filtering using the provided {@link BooleanExpression}, then automatically cloning the returned list
-     * and closing the query.
-     *
-     * <p>
-     *     Typical usage:
-     *     <pre>
-     *          final QToDoItem q = QToDoItem.candidate();
-     *          return executeQuery(ToDoItem.class,
-     *                              q.atPath.eq(atPath).and(
-     *                              q.description.indexOf(description).gt(0))
-     *                              );
-     *     </pre>
-     * </p>
-     */
-    @Programmatic
-    <T> List<T> executeQuery(final Class<T> cls, @Nullable final BooleanExpression filter);
-
-    @Programmatic
-    default <T> List<T> executeQuery(final Class<T> cls) {
-        return executeQuery(cls, null);
-    }
-
-    /**
-     * To perform a common use-case of executing a (type-safe) query against the specified class,
-     * filtering a unique match using the provided {@link BooleanExpression}, then returning
-     * the result and closing the query.
-     *
-     * <p>
-     *     Typical usage:
-     *     <pre>
-     *          final QToDoItem q = QToDoItem.candidate();
-     *          return executeQueryUnique(ToDoItem.class,
-     *                              q.atPath.eq(atPath).and(
-     *                              q.description.eq(description))
-     *                              );
-     *     </pre>
-     * </p>
-     */
-    @Programmatic
-    <T> T executeQueryUnique(final Class<T> cls, @Nullable final BooleanExpression filter);
-
-    @Programmatic
-    default <T> T executeQueryUnique(final Class<T> cls) {
-        return executeQueryUnique(cls, null);
-    }
-
-    /**
-     * To support the execution of type-safe queries using DataNucleus' lower-level APIs
-     * (eg for group by and so on).
-     *
-     * <p>
-     *     Responsibility for cloning any result sets and closing the query is the responsibility
-     *     of the caller.
-     * </p>
-     */
-    @Programmatic
-    <T> JDOQLTypedQuery<T> newTypesafeQuery(Class<T> cls);
-
-    // -- UTILITY
-
-    /**
-     * Fetch Optimization
-     * <p>
-     * From <a href="http://www.datanucleus.org/products/accessplatform/jdo/query.html">DN-5.2</a> ...
-     * <p>
-     * For RDBMS any single-valued member will be fetched in the original SQL query, but with 
-     * multiple-valued members this is not supported. However what will happen is that any 
-     * collection/array field will be retrieved in a single SQL query for all candidate objects 
-     * (by default using an EXISTS subquery); this avoids the "N+1" problem, resulting in 1 original 
-     * SQL query plus 1 SQL query per collection member. Note that you can disable this by either 
-     * not putting multi-valued fields in the FetchPlan, or by setting the query extension 
-     * datanucleus.rdbms.query.multivaluedFetch to none (default is "exists" using the single SQL per field).
-     */
-    @Programmatic
-    default void disableMultivaluedFetch(JDOQLTypedQuery<?> query) {
-        query.extension(RDBMSPropertyNames.PROPERTY_RDBMS_QUERY_MULTIVALUED_FETCH, "none");
-    }
-
-    /**
-     * Fetch Optimization
-     * @see {@link IsisJdoSupport_v3_2#disableMultivaluedFetch(JDOQLTypedQuery)}
-     * @param query
-     */
-    @Programmatic
-    default void disableMultivaluedFetch(Query<?> query) {
-        query.addExtension(RDBMSPropertyNames.PROPERTY_RDBMS_QUERY_MULTIVALUED_FETCH, "none");
-    }
-
-}
diff --git a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/mixins/Persistable_downloadJdoMetadata.java b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/mixins/Persistable_downloadJdoMetadata.java
index 2fb5218..e7e15a2 100644
--- a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/mixins/Persistable_downloadJdoMetadata.java
+++ b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/mixins/Persistable_downloadJdoMetadata.java
@@ -36,7 +36,7 @@ import org.apache.isis.applib.annotation.SemanticsOf;
 import org.apache.isis.applib.mixins.MixinConstants;
 import org.apache.isis.applib.value.Clob;
 import org.apache.isis.commons.internal.base._Strings;
-import org.apache.isis.persistence.jdo.applib.services.IsisJdoSupport;
+import org.apache.isis.persistence.jdo.applib.integration.JdoSupportService;
 
 import lombok.RequiredArgsConstructor;
 
@@ -52,7 +52,7 @@ import lombok.RequiredArgsConstructor;
 @RequiredArgsConstructor
 public class Persistable_downloadJdoMetadata {
 
-    @Inject IsisJdoSupport jdoSupport;
+    @Inject JdoSupportService jdoSupport;
     
     private final Persistable persistable;
 
diff --git a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/IsisModuleJdoIntegration.java b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/IsisModuleJdoIntegration.java
index 95090d3..493e2f7 100644
--- a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/IsisModuleJdoIntegration.java
+++ b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/IsisModuleJdoIntegration.java
@@ -35,7 +35,7 @@ import org.apache.isis.persistence.jdo.applib.IsisModulePersistenceJdoApplib;
 import org.apache.isis.persistence.jdo.datanucleus.IsisModuleJdoProviderDatanucleus;
 import org.apache.isis.persistence.jdo.datanucleus.config.DnSettings;
 import org.apache.isis.persistence.jdo.integration.changetracking.JdoLifecycleListener;
-import org.apache.isis.persistence.jdo.integration.jdosupport.IsisJdoSupportDN5;
+import org.apache.isis.persistence.jdo.integration.jdosupport.JdoSupportServiceDefault;
 import org.apache.isis.persistence.jdo.integration.metamodel.JdoIntegrationProgrammingModel;
 import org.apache.isis.persistence.jdo.integration.schema.JdoSchemaService;
 import org.apache.isis.persistence.jdo.metamodel.IsisModuleJdoMetamodel;
@@ -56,7 +56,7 @@ import lombok.val;
         // @Component's
         JdoIntegrationProgrammingModel.class,
         
-        IsisJdoSupportDN5.class,
+        JdoSupportServiceDefault.class,
         JdoSchemaService.class,
 
 })
diff --git a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/jdosupport/IsisJdoSupportDN5.java b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/jdosupport/JdoSupportServiceDefault.java
similarity index 89%
rename from persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/jdosupport/IsisJdoSupportDN5.java
rename to persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/jdosupport/JdoSupportServiceDefault.java
index b5c6f86..bd004aa 100644
--- a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/jdosupport/IsisJdoSupportDN5.java
+++ b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/jdosupport/JdoSupportServiceDefault.java
@@ -19,8 +19,6 @@
 
 package org.apache.isis.persistence.jdo.integration.jdosupport;
 
-import static org.apache.isis.commons.internal.base._NullSafe.stream;
-
 import java.sql.ResultSet;
 import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
@@ -34,10 +32,12 @@ import javax.inject.Inject;
 import javax.inject.Named;
 import javax.jdo.Extent;
 import javax.jdo.JDOQLTypedQuery;
-import javax.jdo.PersistenceManager;
+import javax.jdo.PersistenceManagerFactory;
+import javax.jdo.Query;
 import javax.jdo.datastore.JDOConnection;
 import javax.jdo.query.BooleanExpression;
 
+import org.datanucleus.store.rdbms.RDBMSPropertyNames;
 import org.springframework.beans.factory.annotation.Qualifier;
 import org.springframework.context.annotation.Primary;
 import org.springframework.core.annotation.Order;
@@ -49,29 +49,32 @@ import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.commons.internal.collections._Maps;
 import org.apache.isis.core.metamodel.adapter.oid.ObjectPersistenceException;
 import org.apache.isis.core.metamodel.context.MetaModelContext;
-import org.apache.isis.persistence.jdo.applib.services.IsisJdoSupport_v3_2;
+import org.apache.isis.persistence.jdo.applib.integration.JdoSupportService;
 import org.apache.isis.persistence.jdo.spring.integration.TransactionAwarePersistenceManagerFactoryProxy;
 
+import static org.apache.isis.commons.internal.base._NullSafe.stream;
+
 import lombok.val;
 
 
 /**
- * This service provides a number of utility methods to supplement/support the capabilities of the JDO Objectstore.
+ * This service provides a number of utility methods to supplement/support 
+ * the capabilities of the JDO Objectstore.
  *
  */
 @Service
-@Named("isisJdoIntegration.IsisJdoSupport_v3_2")
+@Named("isisJdoIntegration.JdoSupportServiceDefault")
 @Order(OrderPrecedence.MIDPOINT)
 @Primary
 @Qualifier("DN5")
-public class IsisJdoSupportDN5 implements IsisJdoSupport_v3_2 {
+public class JdoSupportServiceDefault implements JdoSupportService {
 
     @Inject private TransactionAwarePersistenceManagerFactoryProxy pmf;
     @Inject private MetaModelContext mmc;
-    
+
     @Override
-    public PersistenceManager getPersistenceManager() {
-        return pmf.getPersistenceManager();
+    public PersistenceManagerFactory getPersistenceManagerFactory() {
+        return pmf.getPersistenceManagerFactory();
     }
     
     @Override
@@ -220,5 +223,15 @@ public class IsisJdoSupportDN5 implements IsisJdoSupport_v3_2 {
         }
     }
 
+    @Override
+    public void disableMultivaluedFetch(JDOQLTypedQuery<?> query) {
+        query.extension(RDBMSPropertyNames.PROPERTY_RDBMS_QUERY_MULTIVALUED_FETCH, "none");
+    }
+
+    @Override
+    public void disableMultivaluedFetch(Query<?> query) {
+        query.addExtension(RDBMSPropertyNames.PROPERTY_RDBMS_QUERY_MULTIVALUED_FETCH, "none");
+    }
+
 
 }
diff --git a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/metamodel/facets/entity/JdoEntityFacet.java b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/metamodel/facets/entity/JdoEntityFacet.java
index de736ca..e5f1db3 100644
--- a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/metamodel/facets/entity/JdoEntityFacet.java
+++ b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/metamodel/facets/entity/JdoEntityFacet.java
@@ -331,7 +331,7 @@ implements EntityFacet {
         if(pmf==null) {
             getFacetHolder().getServiceInjector().injectServicesInto(this);
         }
-        return pmf.getPersistenceManager();
+        return pmf.getPersistenceManagerFactory().getPersistenceManager();
     }
     
     private TransactionalProcessor getTransactionalProcessor() {
diff --git a/persistence/jdo/metamodel/src/main/java/org/apache/isis/persistence/jdo/metamodel/menu/JdoMetamodelMenu.java b/persistence/jdo/metamodel/src/main/java/org/apache/isis/persistence/jdo/metamodel/menu/JdoMetamodelMenu.java
index bceeb37..787f29b 100644
--- a/persistence/jdo/metamodel/src/main/java/org/apache/isis/persistence/jdo/metamodel/menu/JdoMetamodelMenu.java
+++ b/persistence/jdo/metamodel/src/main/java/org/apache/isis/persistence/jdo/metamodel/menu/JdoMetamodelMenu.java
@@ -35,7 +35,7 @@ import org.apache.isis.applib.util.ZipWriter;
 import org.apache.isis.applib.value.Blob;
 import org.apache.isis.applib.value.NamedWithMimeType.CommonMimeType;
 import org.apache.isis.core.config.beans.IsisBeanTypeRegistry;
-import org.apache.isis.persistence.jdo.applib.services.IsisJdoSupport;
+import org.apache.isis.persistence.jdo.applib.integration.JdoSupportService;
 import org.apache.isis.persistence.jdo.provider.entities.JdoFacetContext;
 
 import lombok.val;
@@ -49,7 +49,7 @@ import lombok.val;
 public class JdoMetamodelMenu {
 
     @Inject private IsisBeanTypeRegistry isisBeanTypeRegistry;
-    @Inject private IsisJdoSupport jdoSupport;
+    @Inject private JdoSupportService jdoSupport;
     @Inject private JdoFacetContext jdoFacetContext;
     
     public static abstract class ActionDomainEvent
diff --git a/persistence/jdo/spring/src/main/java/org/apache/isis/persistence/jdo/spring/integration/TransactionAwarePersistenceManagerFactoryProxy.java b/persistence/jdo/spring/src/main/java/org/apache/isis/persistence/jdo/spring/integration/TransactionAwarePersistenceManagerFactoryProxy.java
index 7879b84..f0cb0a4 100644
--- a/persistence/jdo/spring/src/main/java/org/apache/isis/persistence/jdo/spring/integration/TransactionAwarePersistenceManagerFactoryProxy.java
+++ b/persistence/jdo/spring/src/main/java/org/apache/isis/persistence/jdo/spring/integration/TransactionAwarePersistenceManagerFactoryProxy.java
@@ -30,8 +30,6 @@ import org.springframework.beans.factory.FactoryBean;
 import org.springframework.util.Assert;
 import org.springframework.util.ClassUtils;
 
-import org.apache.isis.persistence.jdo.applib.integration.JdoSupportService;
-
 /**
  * Proxy for a target JDO {@link javax.jdo.PersistenceManagerFactory},
  * returning the current thread-bound PersistenceManager (the Spring-managed
@@ -66,8 +64,7 @@ import org.apache.isis.persistence.jdo.applib.integration.JdoSupportService;
  */
 public class TransactionAwarePersistenceManagerFactoryProxy 
 implements 
-    FactoryBean<PersistenceManagerFactory>, 
-    JdoSupportService {
+    FactoryBean<PersistenceManagerFactory> {
 
 	private PersistenceManagerFactory target;
 
@@ -221,9 +218,6 @@ implements
 		}
 	}
 
-	// -- JDO SUPPORT SERVICE
-	
-    @Override
     public PersistenceManagerFactory getPersistenceManagerFactory() {
         return getObject();
     }
diff --git a/subdomains/excel/fixture/src/main/java/org/apache/isis/subdomains/excel/fixtures/demoapp/todomodule/fixturescripts/ExcelDemoToDoItem_tearDown2.java b/subdomains/excel/fixture/src/main/java/org/apache/isis/subdomains/excel/fixtures/demoapp/todomodule/fixturescripts/ExcelDemoToDoItem_tearDown2.java
index f5cae04..f5f9f8f 100644
--- a/subdomains/excel/fixture/src/main/java/org/apache/isis/subdomains/excel/fixtures/demoapp/todomodule/fixturescripts/ExcelDemoToDoItem_tearDown2.java
+++ b/subdomains/excel/fixture/src/main/java/org/apache/isis/subdomains/excel/fixtures/demoapp/todomodule/fixturescripts/ExcelDemoToDoItem_tearDown2.java
@@ -20,7 +20,7 @@ package org.apache.isis.subdomains.excel.fixtures.demoapp.todomodule.fixturescri
 
 import javax.inject.Inject;
 
-import org.apache.isis.persistence.jdo.applib.services.IsisJdoSupport;
+import org.apache.isis.persistence.jdo.applib.integration.JdoSupportService;
 import org.apache.isis.testing.fixtures.applib.fixturescripts.FixtureScript;
 
 public class ExcelDemoToDoItem_tearDown2 extends FixtureScript {
@@ -40,19 +40,19 @@ public class ExcelDemoToDoItem_tearDown2 extends FixtureScript {
 
         final String ownedBy = this.user != null ? this.user : userService.currentUserNameElseNobody();
 
-        isisJdoSupport.executeUpdate(String.format(
+        jdoSupport.executeUpdate(String.format(
                 "delete "
                         + "from \"excelFixture\".\"ExcelDemoToDoItemDependencies\" "
                         + "where \"dependingId\" IN "
                         + "(select \"id\" from \"excelFixture\".\"ExcelDemoToDoItem\" where \"ownedBy\" = '%s') ",
                 ownedBy));
 
-        isisJdoSupport.executeUpdate(String.format(
+        jdoSupport.executeUpdate(String.format(
                 "delete from \"excelFixture\".\"ExcelDemoToDoItem\" "
                         + "where \"ownedBy\" = '%s'", ownedBy));
     }
 
 
-    @Inject IsisJdoSupport isisJdoSupport;
+    @Inject JdoSupportService jdoSupport;
 
 }
diff --git a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/teardown/TeardownFixtureAbstract.java b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/teardown/TeardownFixtureAbstract.java
index 796e399..c08ef48 100644
--- a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/teardown/TeardownFixtureAbstract.java
+++ b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/teardown/TeardownFixtureAbstract.java
@@ -28,7 +28,7 @@ import javax.jdo.metadata.TypeMetadata;
 
 import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.commons.internal.base._Strings;
-import org.apache.isis.persistence.jdo.applib.services.IsisJdoSupport;
+import org.apache.isis.persistence.jdo.applib.integration.JdoSupportService;
 import org.apache.isis.testing.fixtures.applib.fixturescripts.FixtureScript;
 
 @Programmatic
@@ -41,7 +41,7 @@ public abstract class TeardownFixtureAbstract extends FixtureScript {
 
         final String value = discriminatorValueOf(cls);
         if(value == null) {
-            final TypeMetadata metadata = isisJdoSupport.getPersistenceManager()
+            final TypeMetadata metadata = jdoSupport.getPersistenceManager()
                             .getPersistenceManagerFactory().getMetadata(cls.getName());
             if(metadata == null) {
                 // fall-back
@@ -78,12 +78,12 @@ public abstract class TeardownFixtureAbstract extends FixtureScript {
         if (_Strings.isNullOrEmpty(schema)) {
             return deleteFrom(table);
         } else {
-            return isisJdoSupport.executeUpdate(String.format("DELETE FROM \"%s\".\"%s\"", schema, table));
+            return jdoSupport.executeUpdate(String.format("DELETE FROM \"%s\".\"%s\"", schema, table));
         }
     }
 
     protected Integer deleteFrom(final String table) {
-        return isisJdoSupport.executeUpdate(String.format("DELETE FROM \"%s\"", table));
+        return jdoSupport.executeUpdate(String.format("DELETE FROM \"%s\"", table));
     }
 
 
@@ -94,7 +94,7 @@ public abstract class TeardownFixtureAbstract extends FixtureScript {
             final String sql = String.format(
                     "DELETE FROM \"%s\".\"%s\" WHERE \"%s\"='%s'",
                     schema, table, column, value);
-            return this.isisJdoSupport.executeUpdate(sql);
+            return this.jdoSupport.executeUpdate(sql);
         }
     }
 
@@ -102,7 +102,7 @@ public abstract class TeardownFixtureAbstract extends FixtureScript {
         final String sql = String.format(
                 "DELETE FROM \"%s\" WHERE \"%s\"='%s'",
                 table, column, value);
-        return this.isisJdoSupport.executeUpdate(sql);
+        return this.jdoSupport.executeUpdate(sql);
     }
 
 
@@ -173,10 +173,10 @@ public abstract class TeardownFixtureAbstract extends FixtureScript {
     }
 
     private PersistenceManagerFactory getPersistenceManagerFactory() {
-        return isisJdoSupport.getPersistenceManager().getPersistenceManagerFactory();
+        return jdoSupport.getPersistenceManager().getPersistenceManagerFactory();
     }
 
-    @Inject private IsisJdoSupport isisJdoSupport;
+    @Inject private JdoSupportService jdoSupport;
 
 
 }