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 2022/08/04 09:31:03 UTC

[isis] 03/12: ISIS-3110: factors out persistence-commons

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

danhaywood pushed a commit to branch ISIS-3110
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 15d4901117b9500367dc5a70ad820fb30abe8053
Author: Dan Haywood <da...@haywood-associates.co.uk>
AuthorDate: Wed Aug 3 13:38:06 2022 +0100

    ISIS-3110: factors out persistence-commons
---
 core/pom.xml                                       |   6 +
 persistence/{jdo/integration => commons}/pom.xml   |  36 +-
 .../commons/IsisModulePersistenceCommons.java}     |  15 +-
 .../EntityChangeTrackerDefault.java}               |  19 +-
 .../changetracking/_ChangingEntitiesFactory.java   |   3 +-
 .../changetracking/_SimpleChangingEntities.java    |   0
 .../jpa/integration/changetracking/_Xray.java      |   3 +-
 persistence/jdo/integration/pom.xml                |  10 +-
 .../IsisModulePersistenceJdoIntegration.java       |   5 +-
 .../changetracking/EntityChangeTrackerJdo.java     | 430 ---------------------
 .../changetracking/_ChangingEntitiesFactory.java   | 143 -------
 .../changetracking/_SimpleChangingEntities.java    | 121 ------
 .../jdo/integration/changetracking/_Xray.java      | 145 -------
 persistence/jpa/integration/pom.xml                |  41 +-
 .../IsisModulePersistenceJpaIntegration.java       |   4 +-
 15 files changed, 68 insertions(+), 913 deletions(-)

diff --git a/core/pom.xml b/core/pom.xml
index f43d342c73..d8d36b8915 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -572,6 +572,11 @@
 				<artifactId>isis-core-codegen-bytebuddy</artifactId>
 				<version>2.0.0-SNAPSHOT</version>
 			</dependency>
+			<dependency>
+				<groupId>org.apache.isis.persistence</groupId>
+				<artifactId>isis-persistence-commons</artifactId>
+				<version>2.0.0-SNAPSHOT</version>
+			</dependency>
 			<dependency>
 				<groupId>org.apache.isis.persistence</groupId>
 				<artifactId>isis-persistence-jdo-applib</artifactId>
@@ -1628,6 +1633,7 @@
 		<module>../viewers/restfulobjects</module>
 		<module>../viewers/wicket</module>
 
+		<module>../persistence/commons</module>
 		<module>../persistence/jdo</module>
 		<module>../persistence/jpa</module>
 
diff --git a/persistence/jdo/integration/pom.xml b/persistence/commons/pom.xml
similarity index 62%
copy from persistence/jdo/integration/pom.xml
copy to persistence/commons/pom.xml
index f684aa5350..b8e9a17c2a 100644
--- a/persistence/jdo/integration/pom.xml
+++ b/persistence/commons/pom.xml
@@ -14,30 +14,27 @@
 	<modelVersion>4.0.0</modelVersion>
 
 	<parent>
-		<groupId>org.apache.isis.persistence</groupId>
-		<artifactId>isis-persistence-jdo</artifactId>
+		<groupId>org.apache.isis.core</groupId>
+		<artifactId>isis-core</artifactId>
 		<version>2.0.0-SNAPSHOT</version>
+		<relativePath>../../core/pom.xml</relativePath>
 	</parent>
 
-	<artifactId>isis-persistence-jdo-integration</artifactId>
+	<groupId>org.apache.isis.persistence</groupId>
+	<artifactId>isis-persistence-commons</artifactId>
 
-	<name>Apache Isis Persistence - JDO (integration)</name>
+	<name>Apache Isis Persistence - Commons</name>
 	<description>
-        JDO Integration (powered by DataNucleus)
+		Apache Isis Common utilities for persistence stacks
     </description>
 
 	<properties>
-		<jar-plugin.automaticModuleName>org.apache.isis.persistence.jdo.integration</jar-plugin.automaticModuleName>
-		<git-plugin.propertiesDir>org/apache/isis/persistence/jdo/integration</git-plugin.propertiesDir>
+		<jar-plugin.automaticModuleName>org.apache.isis.persistence.commons</jar-plugin.automaticModuleName>
+		<git-plugin.propertiesDir>org/apache/isis/persistence/commons</git-plugin.propertiesDir>
 	</properties>
 
 	<dependencies>
 
-<!-- 		<dependency> -->
-<!-- 			<groupId>org.apache.isis.persistence</groupId> -->
-<!-- 			<artifactId>isis-persistence-jdo-provider</artifactId> -->
-<!-- 		</dependency> -->
-
 		<dependency>
 			<groupId>org.apache.isis.commons</groupId>
 			<artifactId>isis-commons</artifactId>
@@ -53,21 +50,6 @@
 			<artifactId>isis-core-runtime</artifactId>
 		</dependency>
 
-		<dependency>
-			<groupId>org.apache.isis.persistence</groupId>
-			<artifactId>isis-persistence-jdo-applib</artifactId>
-		</dependency>
-
-		<dependency>
-			<groupId>org.apache.isis.persistence</groupId>
-			<artifactId>isis-persistence-jdo-metamodel</artifactId>
-		</dependency>
-
-		<dependency>
-			<groupId>org.apache.isis.persistence</groupId>
-			<artifactId>isis-persistence-jdo-spring</artifactId>
-		</dependency>
-
 		<!-- TESTING -->
 
         <dependency>
diff --git a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/IsisModulePersistenceJdoIntegration.java b/persistence/commons/src/main/java/org/apache/isis/persistence/commons/IsisModulePersistenceCommons.java
similarity index 68%
copy from persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/IsisModulePersistenceJdoIntegration.java
copy to persistence/commons/src/main/java/org/apache/isis/persistence/commons/IsisModulePersistenceCommons.java
index aa7a5c07db..c2613ac727 100644
--- a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/IsisModulePersistenceJdoIntegration.java
+++ b/persistence/commons/src/main/java/org/apache/isis/persistence/commons/IsisModulePersistenceCommons.java
@@ -16,26 +16,23 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.persistence.jdo.integration;
+package org.apache.isis.persistence.commons;
 
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Import;
 
 import org.apache.isis.core.runtime.IsisModuleCoreRuntime;
-import org.apache.isis.persistence.jdo.applib.IsisModulePersistenceJdoApplib;
-import org.apache.isis.persistence.jdo.integration.changetracking.EntityChangeTrackerJdo;
-import org.apache.isis.persistence.jdo.metamodel.IsisModulePersistenceJdoMetamodel;
+import org.apache.isis.persistence.jpa.integration.changetracking.EntityChangeTrackerDefault;
 
 @Configuration
 @Import({
         // modules
         IsisModuleCoreRuntime.class,
-        IsisModulePersistenceJdoApplib.class,
-        IsisModulePersistenceJdoMetamodel.class,
 
-        // services
-        EntityChangeTrackerJdo.class,
+        // @Service's
+        EntityChangeTrackerDefault.class,
+
 })
-public class IsisModulePersistenceJdoIntegration {
+public class IsisModulePersistenceCommons {
 
 }
diff --git a/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/changetracking/EntityChangeTrackerJpa.java b/persistence/commons/src/main/java/org/apache/isis/persistence/jpa/integration/changetracking/EntityChangeTrackerDefault.java
similarity index 98%
rename from persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/changetracking/EntityChangeTrackerJpa.java
rename to persistence/commons/src/main/java/org/apache/isis/persistence/jpa/integration/changetracking/EntityChangeTrackerDefault.java
index 2cee271ff1..91cbbfeaa9 100644
--- a/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/changetracking/EntityChangeTrackerJpa.java
+++ b/persistence/commons/src/main/java/org/apache/isis/persistence/jpa/integration/changetracking/EntityChangeTrackerDefault.java
@@ -15,6 +15,7 @@
  *  KIND, either express or implied.  See the License for the
  *  specific language governing permissions and limitations
  *  under the License.
+ *
  */
 package org.apache.isis.persistence.jpa.integration.changetracking;
 
@@ -92,12 +93,12 @@ import lombok.extern.log4j.Log4j2;
  * @since 2.0 {@index}
  */
 @Service
-@Named("isis.transaction.EntityChangeTrackerJpa")
+@Named("isis.persistence.commons.EntityChangeTrackerDefault")
 @Priority(PriorityPrecedence.EARLY)
-@Qualifier("jdo")
+@Qualifier("default")
 @InteractionScope
 @Log4j2
-public class EntityChangeTrackerJpa
+public class EntityChangeTrackerDefault
 extends PersistenceCallbackHandlerAbstract
 implements
     MetricsService,
@@ -148,7 +149,7 @@ implements
     private final Provider<InteractionProvider> interactionProviderProvider;
 
     @Inject
-    public EntityChangeTrackerJpa(
+    public EntityChangeTrackerDefault(
             final EntityPropertyChangePublisher entityPropertyChangePublisher,
             final EntityChangesPublisher entityChangesPublisher,
             final EventBusService eventBusService,
@@ -225,7 +226,6 @@ implements
             return false; // ignore entities that are not enabled for entity change publishing
         }
 
-        // if home-grown
         if(entityPropertyChangeRecordsForPublishing.isMemoized()) {
             throw _Exceptions.illegalState("Cannot enlist additional changes for auditing, "
                     + "since changedObjectPropertiesRef was already prepared (memoized) for auditing.");
@@ -260,14 +260,17 @@ implements
 
     private void postPublishing() {
         log.debug("purging entity change records");
+
+        // if ORM provided property change records ... as in JPA
         this.enlistedPropertyChangesOfCreated.clear();
         this.enlistedPropertyChangesOfUpdated.clear();
         this.enlistedPropertyChangesOfDeleted.clear();
 
-//        propertyChangeRecordsById.clear();
-        changeKindByEnlistedAdapter.clear();
-//        entityPropertyChangeRecordsForPublishing.clear();
+        // if instead we had to infer ourselves (home-grown)... as in JDO
+        propertyChangeRecordsById.clear();
+        entityPropertyChangeRecordsForPublishing.clear();
 
+        changeKindByEnlistedAdapter.clear();
         entityChangeEventCount.reset();
         numberEntitiesLoaded.reset();
     }
diff --git a/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/changetracking/_ChangingEntitiesFactory.java b/persistence/commons/src/main/java/org/apache/isis/persistence/jpa/integration/changetracking/_ChangingEntitiesFactory.java
similarity index 98%
rename from persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/changetracking/_ChangingEntitiesFactory.java
rename to persistence/commons/src/main/java/org/apache/isis/persistence/jpa/integration/changetracking/_ChangingEntitiesFactory.java
index c3e142433f..8b5998f4ac 100644
--- a/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/changetracking/_ChangingEntitiesFactory.java
+++ b/persistence/commons/src/main/java/org/apache/isis/persistence/jpa/integration/changetracking/_ChangingEntitiesFactory.java
@@ -15,6 +15,7 @@
  *  KIND, either express or implied.  See the License for the
  *  specific language governing permissions and limitations
  *  under the License.
+ *
  */
 package org.apache.isis.persistence.jpa.integration.changetracking;
 
@@ -40,7 +41,7 @@ final class _ChangingEntitiesFactory {
     public static Optional<EntityChanges> createChangingEntities(
             final java.sql.Timestamp completedAt,
             final String userName,
-            final EntityChangeTrackerJpa entityChangeTracker) {
+            final EntityChangeTrackerDefault entityChangeTracker) {
 
         if(entityChangeTracker.getChangeKindByEnlistedAdapter().isEmpty()) {
             return Optional.empty();
diff --git a/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/changetracking/_SimpleChangingEntities.java b/persistence/commons/src/main/java/org/apache/isis/persistence/jpa/integration/changetracking/_SimpleChangingEntities.java
similarity index 100%
rename from persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/changetracking/_SimpleChangingEntities.java
rename to persistence/commons/src/main/java/org/apache/isis/persistence/jpa/integration/changetracking/_SimpleChangingEntities.java
diff --git a/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/changetracking/_Xray.java b/persistence/commons/src/main/java/org/apache/isis/persistence/jpa/integration/changetracking/_Xray.java
similarity index 98%
rename from persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/changetracking/_Xray.java
rename to persistence/commons/src/main/java/org/apache/isis/persistence/jpa/integration/changetracking/_Xray.java
index 50955f25fb..7ee2ef86da 100644
--- a/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/changetracking/_Xray.java
+++ b/persistence/commons/src/main/java/org/apache/isis/persistence/jpa/integration/changetracking/_Xray.java
@@ -15,6 +15,7 @@
  *  KIND, either express or implied.  See the License for the
  *  specific language governing permissions and limitations
  *  under the License.
+ *
  */
 package org.apache.isis.persistence.jpa.integration.changetracking;
 
@@ -34,7 +35,7 @@ import lombok.val;
 final class _Xray {
 
     public static void publish(
-            final EntityChangeTrackerJpa entityChangeTrackerDefault,
+            final EntityChangeTrackerDefault entityChangeTrackerDefault,
             final Provider<InteractionProvider> interactionProviderProvider) {
 
         if(!XrayUi.isXrayEnabled()) {
diff --git a/persistence/jdo/integration/pom.xml b/persistence/jdo/integration/pom.xml
index f684aa5350..327e286a0b 100644
--- a/persistence/jdo/integration/pom.xml
+++ b/persistence/jdo/integration/pom.xml
@@ -33,11 +33,6 @@
 
 	<dependencies>
 
-<!-- 		<dependency> -->
-<!-- 			<groupId>org.apache.isis.persistence</groupId> -->
-<!-- 			<artifactId>isis-persistence-jdo-provider</artifactId> -->
-<!-- 		</dependency> -->
-
 		<dependency>
 			<groupId>org.apache.isis.commons</groupId>
 			<artifactId>isis-commons</artifactId>
@@ -53,6 +48,11 @@
 			<artifactId>isis-core-runtime</artifactId>
 		</dependency>
 
+		<dependency>
+			<groupId>org.apache.isis.persistence</groupId>
+			<artifactId>isis-persistence-commons</artifactId>
+		</dependency>
+
 		<dependency>
 			<groupId>org.apache.isis.persistence</groupId>
 			<artifactId>isis-persistence-jdo-applib</artifactId>
diff --git a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/IsisModulePersistenceJdoIntegration.java b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/IsisModulePersistenceJdoIntegration.java
index aa7a5c07db..9c9ccab436 100644
--- a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/IsisModulePersistenceJdoIntegration.java
+++ b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/IsisModulePersistenceJdoIntegration.java
@@ -22,19 +22,18 @@ import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Import;
 
 import org.apache.isis.core.runtime.IsisModuleCoreRuntime;
+import org.apache.isis.persistence.commons.IsisModulePersistenceCommons;
 import org.apache.isis.persistence.jdo.applib.IsisModulePersistenceJdoApplib;
-import org.apache.isis.persistence.jdo.integration.changetracking.EntityChangeTrackerJdo;
 import org.apache.isis.persistence.jdo.metamodel.IsisModulePersistenceJdoMetamodel;
 
 @Configuration
 @Import({
         // modules
         IsisModuleCoreRuntime.class,
+        IsisModulePersistenceCommons.class,
         IsisModulePersistenceJdoApplib.class,
         IsisModulePersistenceJdoMetamodel.class,
 
-        // services
-        EntityChangeTrackerJdo.class,
 })
 public class IsisModulePersistenceJdoIntegration {
 
diff --git a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/changetracking/EntityChangeTrackerJdo.java b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/changetracking/EntityChangeTrackerJdo.java
deleted file mode 100644
index fd39f99375..0000000000
--- a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/changetracking/EntityChangeTrackerJdo.java
+++ /dev/null
@@ -1,430 +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.integration.changetracking;
-
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.LongAdder;
-import java.util.function.Consumer;
-
-import javax.annotation.Priority;
-import javax.inject.Inject;
-import javax.inject.Named;
-import javax.inject.Provider;
-
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.context.event.EventListener;
-import org.springframework.core.annotation.Order;
-import org.springframework.stereotype.Service;
-
-import org.apache.isis.applib.annotation.EntityChangeKind;
-import org.apache.isis.applib.annotation.InteractionScope;
-import org.apache.isis.applib.annotation.PriorityPrecedence;
-import org.apache.isis.applib.services.bookmark.Bookmark;
-import org.apache.isis.applib.services.eventbus.EventBusService;
-import org.apache.isis.applib.services.iactn.Interaction;
-import org.apache.isis.applib.services.iactn.InteractionProvider;
-import org.apache.isis.applib.services.metrics.MetricsService;
-import org.apache.isis.applib.services.publishing.spi.EntityChanges;
-import org.apache.isis.applib.services.publishing.spi.EntityPropertyChange;
-import org.apache.isis.applib.services.xactn.TransactionId;
-import org.apache.isis.commons.collections.Can;
-import org.apache.isis.commons.internal.base._Lazy;
-import org.apache.isis.commons.internal.collections._Maps;
-import org.apache.isis.commons.internal.collections._Sets;
-import org.apache.isis.commons.internal.exceptions._Exceptions;
-import org.apache.isis.core.metamodel.facets.object.callbacks.CallbackFacet;
-import org.apache.isis.core.metamodel.facets.object.callbacks.LoadedCallbackFacet;
-import org.apache.isis.core.metamodel.facets.object.callbacks.LoadedLifecycleEventFacet;
-import org.apache.isis.core.metamodel.facets.object.callbacks.PersistedCallbackFacet;
-import org.apache.isis.core.metamodel.facets.object.callbacks.PersistedLifecycleEventFacet;
-import org.apache.isis.core.metamodel.facets.object.callbacks.PersistingCallbackFacet;
-import org.apache.isis.core.metamodel.facets.object.callbacks.PersistingLifecycleEventFacet;
-import org.apache.isis.core.metamodel.facets.object.callbacks.RemovingCallbackFacet;
-import org.apache.isis.core.metamodel.facets.object.callbacks.RemovingLifecycleEventFacet;
-import org.apache.isis.core.metamodel.facets.object.callbacks.UpdatedCallbackFacet;
-import org.apache.isis.core.metamodel.facets.object.callbacks.UpdatedLifecycleEventFacet;
-import org.apache.isis.core.metamodel.facets.object.callbacks.UpdatingCallbackFacet;
-import org.apache.isis.core.metamodel.facets.object.callbacks.UpdatingLifecycleEventFacet;
-import org.apache.isis.core.metamodel.facets.object.publish.entitychange.EntityChangePublishingFacet;
-import org.apache.isis.core.metamodel.facets.properties.property.entitychangepublishing.EntityPropertyChangePublishingPolicyFacet;
-import org.apache.isis.core.metamodel.services.objectlifecycle.HasEnlistedEntityPropertyChanges;
-import org.apache.isis.core.metamodel.services.objectlifecycle.PropertyChangeRecord;
-import org.apache.isis.core.metamodel.services.objectlifecycle.PropertyValuePlaceholder;
-import org.apache.isis.core.metamodel.spec.ManagedObject;
-import org.apache.isis.core.metamodel.spec.ManagedObjects;
-import org.apache.isis.core.metamodel.spec.ManagedObjects.EntityUtil;
-import org.apache.isis.core.metamodel.spec.feature.MixedIn;
-import org.apache.isis.core.transaction.changetracking.EntityChangeTracker;
-import org.apache.isis.core.transaction.changetracking.EntityChangesPublisher;
-import org.apache.isis.core.transaction.changetracking.EntityPropertyChangePublisher;
-import org.apache.isis.core.transaction.changetracking.HasEnlistedEntityChanges;
-import org.apache.isis.core.transaction.changetracking.PersistenceCallbackHandlerAbstract;
-import org.apache.isis.core.transaction.events.TransactionBeforeCompletionEvent;
-
-import lombok.AccessLevel;
-import lombok.Getter;
-import lombok.NonNull;
-import lombok.val;
-import lombok.extern.log4j.Log4j2;
-
-/**
- * @since 2.0 {@index}
- */
-@Service
-@Named("isis.transaction.EntityChangeTrackerJdo")
-@Priority(PriorityPrecedence.EARLY)
-@Qualifier("jdo")
-@InteractionScope
-@Log4j2
-public class EntityChangeTrackerJdo
-extends PersistenceCallbackHandlerAbstract
-implements
-    MetricsService,
-    EntityChangeTracker,
-    HasEnlistedEntityPropertyChanges,
-    HasEnlistedEntityChanges {
-
-    /**
-     * Contains initial change records having set the pre-values of every property of every object that was enlisted.
-     */
-    private final Map<String, PropertyChangeRecord> propertyChangeRecordsById = _Maps.newLinkedHashMap();
-
-    /**
-     * Contains pre- and post- values of every property of every object that actually changed. A lazy snapshot,
-     * triggered by internal call to {@link #snapshotPropertyChangeRecords()}.
-     */
-    private final _Lazy<Set<PropertyChangeRecord>> entityPropertyChangeRecordsForPublishing
-        = _Lazy.threadSafe(this::capturePostValuesAndDrain);
-
-    @Getter(AccessLevel.PACKAGE)
-    private final Map<Bookmark, EntityChangeKind> changeKindByEnlistedAdapter = _Maps.newLinkedHashMap();
-
-    private final EntityPropertyChangePublisher entityPropertyChangePublisher;
-    private final EntityChangesPublisher entityChangesPublisher;
-    private final Provider<InteractionProvider> interactionProviderProvider;
-
-    @Inject
-    public EntityChangeTrackerJdo(
-            final EntityPropertyChangePublisher entityPropertyChangePublisher,
-            final EntityChangesPublisher entityChangesPublisher,
-            final EventBusService eventBusService,
-            final Provider<InteractionProvider> interactionProviderProvider) {
-        super(eventBusService);
-        this.entityPropertyChangePublisher = entityPropertyChangePublisher;
-        this.entityChangesPublisher = entityChangesPublisher;
-        this.interactionProviderProvider = interactionProviderProvider;
-    }
-
-    private boolean isEnlisted(final @NonNull ManagedObject adapter) {
-        return ManagedObjects.bookmark(adapter)
-        .map(changeKindByEnlistedAdapter::containsKey)
-        .orElse(false);
-    }
-
-    private void enlistCreatedInternal(final @NonNull ManagedObject adapter) {
-        if(!isEntityEnabledForChangePublishing(adapter)) {
-            return;
-        }
-        enlistForChangeKindPublishing(adapter, EntityChangeKind.CREATE);
-        enlistForPreAndPostValuePublishing(adapter, record->record.setPreValue(PropertyValuePlaceholder.NEW));
-    }
-
-    private void enlistUpdatingInternal(
-            final @NonNull ManagedObject entity) {
-        if(!isEntityEnabledForChangePublishing(entity)) {
-            return;
-        }
-        enlistForChangeKindPublishing(entity, EntityChangeKind.UPDATE);
-        enlistForPreAndPostValuePublishing(entity, PropertyChangeRecord::updatePreValue);
-    }
-
-    private void enlistDeletingInternal(final @NonNull ManagedObject adapter) {
-        if(!isEntityEnabledForChangePublishing(adapter)) {
-            return;
-        }
-        final boolean enlisted = enlistForChangeKindPublishing(adapter, EntityChangeKind.DELETE);
-        if(enlisted) {
-            enlistForPreAndPostValuePublishing(adapter, PropertyChangeRecord::updatePreValue);
-        }
-    }
-
-    Set<PropertyChangeRecord> snapshotPropertyChangeRecords() {
-        // this code path has side-effects, it locks the result for this transaction,
-        // such that cannot enlist on top of it
-        return entityPropertyChangeRecordsForPublishing.get();
-    }
-
-    private boolean isEntityEnabledForChangePublishing(final @NonNull ManagedObject adapter) {
-
-        if(!EntityChangePublishingFacet.isPublishingEnabled(adapter.getSpecification())) {
-            return false; // ignore entities that are not enabled for entity change publishing
-        }
-
-        if(entityPropertyChangeRecordsForPublishing.isMemoized()) {
-            throw _Exceptions.illegalState("Cannot enlist additional changes for auditing, "
-                    + "since changedObjectPropertiesRef was already prepared (memoized) for auditing.");
-        }
-
-        entityChangeEventCount.increment();
-        enableCommandPublishing();
-
-        return true;
-    }
-
-    /**
-     * TRANSACTION END BOUNDARY
-     * @apiNote intended to be called during before transaction completion by the framework internally
-     */
-    @EventListener(value = TransactionBeforeCompletionEvent.class) @Order(PriorityPrecedence.LATE)
-    public void onTransactionCompleting(final TransactionBeforeCompletionEvent event) {
-        try {
-            doPublish();
-        } finally {
-            postPublishing();
-        }
-    }
-
-    private void doPublish() {
-        _Xray.publish(this, interactionProviderProvider);
-
-        log.debug("about to publish entity changes");
-        entityPropertyChangePublisher.publishChangedProperties(this);
-        entityChangesPublisher.publishChangingEntities(this);
-    }
-
-    private void postPublishing() {
-        log.debug("purging entity change records");
-        propertyChangeRecordsById.clear();
-        changeKindByEnlistedAdapter.clear();
-        entityPropertyChangeRecordsForPublishing.clear();
-        entityChangeEventCount.reset();
-        numberEntitiesLoaded.reset();
-    }
-
-    private void enableCommandPublishing() {
-        val alreadySet = persistentChangesEncountered.getAndSet(true);
-        if(!alreadySet) {
-            val command = currentInteraction().getCommand();
-            command.updater().setSystemStateChanged(true);
-        }
-    }
-
-    @Override
-    public Optional<EntityChanges> getEntityChanges(
-            final java.sql.Timestamp timestamp,
-            final String userName) {
-        return _ChangingEntitiesFactory.createChangingEntities(timestamp, userName, this);
-    }
-
-    @Override
-    public Can<EntityPropertyChange> getPropertyChanges(
-            final java.sql.Timestamp timestamp,
-            final String userName,
-            final TransactionId txId) {
-
-        return snapshotPropertyChangeRecords().stream()
-                .map(propertyChangeRecord -> propertyChangeRecord.toEntityPropertyChange(timestamp, userName, txId))
-                .collect(Can.toCan());
-    }
-
-    // -- DEPENDENCIES
-
-    Interaction currentInteraction() {
-        return interactionProviderProvider.get().currentInteractionElseFail();
-    }
-
-    // -- HELPER
-
-    /**
-     * @return <code>true</code> if successfully enlisted, <code>false</code> if was already enlisted
-     */
-    private boolean enlistForChangeKindPublishing(
-            final @NonNull ManagedObject entity,
-            final @NonNull EntityChangeKind changeKind) {
-
-        val bookmark = ManagedObjects.bookmarkElseFail(entity);
-
-        val previousChangeKind = changeKindByEnlistedAdapter.get(bookmark);
-        if(previousChangeKind == null) {
-            changeKindByEnlistedAdapter.put(bookmark, changeKind);
-            return true;
-        }
-        switch (previousChangeKind) {
-        case CREATE:
-            switch (changeKind) {
-            case DELETE:
-                changeKindByEnlistedAdapter.remove(bookmark);
-            case CREATE:
-            case UPDATE:
-                return false;
-            }
-            break;
-        case UPDATE:
-            switch (changeKind) {
-            case DELETE:
-                changeKindByEnlistedAdapter.put(bookmark, changeKind);
-                return true;
-            case CREATE:
-            case UPDATE:
-                return false;
-            }
-            break;
-        case DELETE:
-            return false;
-        }
-        return previousChangeKind == null;
-    }
-
-    private void enlistForPreAndPostValuePublishing(
-            final ManagedObject entity,
-            final Consumer<PropertyChangeRecord> onNewChangeRecord) {
-
-        log.debug("enlist entity's property changes for publishing {}", entity);
-
-        entity.getSpecification().streamProperties(MixedIn.EXCLUDED)
-        .filter(property->!EntityPropertyChangePublishingPolicyFacet.isExcludedFromPublishing(property))
-        .map(property->PropertyChangeRecord.of(entity, property))
-        .filter(record->!propertyChangeRecordsById.containsKey(record.getPropertyId())) // already enlisted, so ignore
-        .forEach(record->{
-            onNewChangeRecord.accept(record);
-            propertyChangeRecordsById.put(record.getPropertyId(), record);
-        });
-    }
-
-    /**
-     * For any enlisted Object Properties collects those, that are meant for publishing,
-     * then clears enlisted objects.
-     */
-    private Set<PropertyChangeRecord> capturePostValuesAndDrain() {
-
-        val records = propertyChangeRecordsById.values().stream()
-                // set post values, which have been left empty up to now
-                .peek(rec->{
-                    // assuming this check correctly detects deleted entities (JDO)
-                    if(EntityUtil.isDetachedOrRemoved(rec.getEntity())) {
-                        rec.updatePostValueAsDeleted();
-                    } else {
-                        rec.updatePostValueAsNonDeleted();
-                    }
-                })
-                .filter(managedProperty->managedProperty.getPreAndPostValue().shouldPublish())
-                .collect(_Sets.toUnmodifiable());
-
-        propertyChangeRecordsById.clear();
-
-        return records;
-
-    }
-
-    // side-effect free, used by XRay
-    long countPotentialPropertyChangeRecords() {
-        return propertyChangeRecordsById.size();
-    }
-
-    // -- METRICS SERVICE
-
-    @Override
-    public int numberEntitiesLoaded() {
-        return Math.toIntExact(numberEntitiesLoaded.longValue());
-    }
-
-    @Override
-    public int numberEntitiesDirtied() {
-        return changeKindByEnlistedAdapter.size();
-    }
-
-    // -- ENTITY CHANGE TRACKING
-
-    @Override
-    public void enlistCreated(final ManagedObject entity) {
-        _Xray.enlistCreated(entity, interactionProviderProvider);
-        val hasAlreadyBeenEnlisted = isEnlisted(entity);
-        enlistCreatedInternal(entity);
-
-        if(!hasAlreadyBeenEnlisted) {
-            CallbackFacet.callCallback(entity, PersistedCallbackFacet.class);
-            postLifecycleEventIfRequired(entity, PersistedLifecycleEventFacet.class);
-        }
-    }
-
-    @Override
-    public void enlistCreated(ManagedObject entity, Can<PropertyChangeRecord> propertyChangeRecords) {
-    }
-
-    @Override
-    public void enlistDeleting(final ManagedObject entity) {
-        _Xray.enlistDeleting(entity, interactionProviderProvider);
-        enlistDeletingInternal(entity);
-        CallbackFacet.callCallback(entity, RemovingCallbackFacet.class);
-        postLifecycleEventIfRequired(entity, RemovingLifecycleEventFacet.class);
-    }
-
-    @Override
-    public void enlistDeleting(ManagedObject entity, Can<PropertyChangeRecord> propertyChangeRecords) {
-    }
-
-    @Override
-    public void enlistUpdating(final ManagedObject entity) {
-        _Xray.enlistUpdating(entity, interactionProviderProvider);
-        val hasAlreadyBeenEnlisted = isEnlisted(entity);
-        // we call this come what may;
-        // additional properties may now have been changed, and the changeKind for publishing might also be modified
-        enlistUpdatingInternal(entity);
-
-        if(!hasAlreadyBeenEnlisted) {
-            // prevent an infinite loop... don't call the 'updating()' callback on this object if we have already done so
-            CallbackFacet.callCallback(entity, UpdatingCallbackFacet.class);
-            postLifecycleEventIfRequired(entity, UpdatingLifecycleEventFacet.class);
-        }
-    }
-
-    @Override
-    public void enlistUpdating(ManagedObject entity, Can<PropertyChangeRecord> propertyChangeRecords) {
-    }
-
-    @Override
-    public void recognizeLoaded(final ManagedObject entity) {
-        _Xray.recognizeLoaded(entity, interactionProviderProvider);
-        CallbackFacet.callCallback(entity, LoadedCallbackFacet.class);
-        postLifecycleEventIfRequired(entity, LoadedLifecycleEventFacet.class);
-        numberEntitiesLoaded.increment();
-    }
-
-    @Override
-    public void recognizePersisting(final ManagedObject entity) {
-        _Xray.recognizePersisting(entity, interactionProviderProvider);
-        CallbackFacet.callCallback(entity, PersistingCallbackFacet.class);
-        postLifecycleEventIfRequired(entity, PersistingLifecycleEventFacet.class);
-    }
-
-    @Override
-    public void recognizeUpdating(final ManagedObject entity) {
-        _Xray.recognizeUpdating(entity, interactionProviderProvider);
-        CallbackFacet.callCallback(entity, UpdatedCallbackFacet.class);
-        postLifecycleEventIfRequired(entity, UpdatedLifecycleEventFacet.class);
-    }
-
-    private final LongAdder numberEntitiesLoaded = new LongAdder();
-    private final LongAdder entityChangeEventCount = new LongAdder();
-    private final AtomicBoolean persistentChangesEncountered = new AtomicBoolean();
-
-}
diff --git a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/changetracking/_ChangingEntitiesFactory.java b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/changetracking/_ChangingEntitiesFactory.java
deleted file mode 100644
index 95b3c3a9df..0000000000
--- a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/changetracking/_ChangingEntitiesFactory.java
+++ /dev/null
@@ -1,143 +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.integration.changetracking;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Optional;
-import java.util.UUID;
-
-import org.apache.isis.applib.annotation.EntityChangeKind;
-import org.apache.isis.applib.jaxb.JavaSqlXMLGregorianCalendarMarshalling;
-import org.apache.isis.applib.services.bookmark.Bookmark;
-import org.apache.isis.applib.services.iactn.Interaction;
-import org.apache.isis.applib.services.publishing.spi.EntityChanges;
-import org.apache.isis.core.metamodel.execution.InteractionInternal;
-import org.apache.isis.schema.chg.v2.ChangesDto;
-import org.apache.isis.schema.chg.v2.ObjectsDto;
-import org.apache.isis.schema.common.v2.OidsDto;
-
-import lombok.val;
-
-final class _ChangingEntitiesFactory {
-
-    public static Optional<EntityChanges> createChangingEntities(
-            final java.sql.Timestamp completedAt,
-            final String userName,
-            final EntityChangeTrackerJdo entityChangeTracker) {
-
-        if(entityChangeTracker.getChangeKindByEnlistedAdapter().isEmpty()) {
-            return Optional.empty();
-        }
-
-        // take a copy of enlisted adapters ... the JDO implementation of the PublishingService
-        // creates further entities which would be enlisted;
-        // taking copy of the map avoids ConcurrentModificationException
-        val changeKindByEnlistedAdapter = new HashMap<>(
-                entityChangeTracker.getChangeKindByEnlistedAdapter());
-
-        val changingEntities = newChangingEntities(
-                completedAt,
-                userName,
-                entityChangeTracker.currentInteraction(),
-                entityChangeTracker.numberEntitiesLoaded(),
-                // side-effect: it locks the result for this transaction,
-                // such that cannot enlist on top of it
-                entityChangeTracker.snapshotPropertyChangeRecords().size(),
-                changeKindByEnlistedAdapter);
-
-        return Optional.of(changingEntities);
-    }
-
-    // -- HELPER
-
-    private static EntityChanges newChangingEntities(
-            final java.sql.Timestamp completedAt,
-            final String userName,
-            final Interaction interaction,
-            final int numberEntitiesLoaded,
-            final int numberEntityPropertiesModified,
-            final Map<Bookmark, EntityChangeKind> changeKindByEnlistedAdapter) {
-
-        val interactionId = interaction.getInteractionId();
-        final int nextEventSequence = ((InteractionInternal) interaction).getThenIncrementTransactionSequence();
-
-        return new _SimpleChangingEntities(
-                    interactionId, nextEventSequence,
-                    userName, completedAt,
-                    numberEntitiesLoaded,
-                    numberEntityPropertiesModified,
-                    ()->newDto(
-                            interactionId, nextEventSequence,
-                            userName, completedAt,
-                            numberEntitiesLoaded,
-                            numberEntityPropertiesModified,
-                            changeKindByEnlistedAdapter));
-    }
-
-    private static ChangesDto newDto(
-            final UUID interactionId, final int transactionSequenceNum,
-            final String userName, final java.sql.Timestamp completedAt,
-            final int numberEntitiesLoaded,
-            final int numberEntityPropertiesModified,
-            final Map<Bookmark, EntityChangeKind> changeKindByEnlistedEntity) {
-
-        val objectsDto = new ObjectsDto();
-        objectsDto.setCreated(new OidsDto());
-        objectsDto.setUpdated(new OidsDto());
-        objectsDto.setDeleted(new OidsDto());
-
-        changeKindByEnlistedEntity.forEach((bookmark, kind)->{
-            val oidDto = bookmark.toOidDto();
-            if(oidDto==null) {
-                return;
-            }
-            switch(kind) {
-            case CREATE:
-                objectsDto.getCreated().getOid().add(oidDto);
-                return;
-            case UPDATE:
-                objectsDto.getUpdated().getOid().add(oidDto);
-                return;
-            case DELETE:
-                objectsDto.getDeleted().getOid().add(oidDto);
-                return;
-            }
-        });
-
-        objectsDto.setLoaded(numberEntitiesLoaded);
-        objectsDto.setPropertiesModified(numberEntityPropertiesModified);
-
-        val changesDto = new ChangesDto();
-
-        changesDto.setMajorVersion("2");
-        changesDto.setMinorVersion("0");
-
-        changesDto.setInteractionId(interactionId.toString());
-        changesDto.setSequence(transactionSequenceNum);
-
-        changesDto.setUsername(userName);
-        changesDto.setCompletedAt(JavaSqlXMLGregorianCalendarMarshalling.toXMLGregorianCalendar(completedAt));
-
-        changesDto.setObjects(objectsDto);
-        return changesDto;
-    }
-
-
-}
diff --git a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/changetracking/_SimpleChangingEntities.java b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/changetracking/_SimpleChangingEntities.java
deleted file mode 100644
index 18b4896d6a..0000000000
--- a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/changetracking/_SimpleChangingEntities.java
+++ /dev/null
@@ -1,121 +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.integration.changetracking;
-
-import java.sql.Timestamp;
-import java.util.UUID;
-import java.util.function.Supplier;
-
-import org.apache.isis.applib.services.publishing.spi.EntityChanges;
-import org.apache.isis.schema.chg.v2.ChangesDto;
-
-import lombok.NonNull;
-import lombok.ToString;
-
-/**
- * Captures which objects were created, updated or deleted in the course of a transaction.
- */
-@ToString
-final class _SimpleChangingEntities implements EntityChanges {
-
-    private UUID transactionUuid;
-    private final int sequence;
-    private final String userName;
-    private final Timestamp completedAt;
-    private final int numberEntitiesLoaded;
-    private final int numberEntityPropertiesModified;
-
-    @ToString.Exclude
-    private final Supplier<ChangesDto> changesDtoSupplier;
-
-    public _SimpleChangingEntities(
-            final @NonNull UUID transactionUuid,
-            final int sequence,
-            final @NonNull String userName,
-            final @NonNull Timestamp completedAt,
-            final int numberEntitiesLoaded,
-            final int numberEntityPropertiesModified,
-            final @NonNull Supplier<ChangesDto> changesDtoSupplier) {
-
-        this.transactionUuid = transactionUuid;
-        this.sequence = sequence;
-        this.userName = userName;
-        this.completedAt = completedAt;
-        this.numberEntitiesLoaded = numberEntitiesLoaded;
-        this.numberEntityPropertiesModified = numberEntityPropertiesModified;
-        this.changesDtoSupplier = changesDtoSupplier;
-    }
-
-    @Override
-    public UUID getInteractionId() {
-        return transactionUuid;
-    }
-
-    @Override
-    public int getSequence() {
-        return sequence;
-    }
-
-    /**
-     * The date/time at which this set of enlisted objects was created
-     * (approx the completion time of the transaction).
-     */
-    @Override
-    public Timestamp getCompletedAt() {
-        return completedAt;
-    }
-
-    @Override
-    public String getUsername() {
-        return userName;
-    }
-
-    private ChangesDto dto;
-
-    @Override
-    public ChangesDto getDto() {
-        return dto != null ? dto : (dto = changesDtoSupplier.get());
-    }
-
-    @Override
-    public int getNumberLoaded() {
-        return numberEntitiesLoaded;
-    }
-
-    @Override
-    public int getNumberCreated() {
-        return getDto().getObjects().getCreated().getOid().size();
-    }
-
-    @Override
-    public int getNumberUpdated() {
-        return getDto().getObjects().getUpdated().getOid().size();
-    }
-
-    @Override
-    public int getNumberDeleted() {
-        return getDto().getObjects().getDeleted().getOid().size();
-    }
-
-    @Override
-    public int getNumberPropertiesModified() {
-        return numberEntityPropertiesModified;
-    }
-
-}
diff --git a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/changetracking/_Xray.java b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/changetracking/_Xray.java
deleted file mode 100644
index 34c16325dd..0000000000
--- a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/changetracking/_Xray.java
+++ /dev/null
@@ -1,145 +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.integration.changetracking;
-
-import java.awt.Color;
-
-import javax.inject.Provider;
-
-import org.apache.isis.applib.services.iactn.InteractionProvider;
-import org.apache.isis.commons.internal.debug._XrayEvent;
-import org.apache.isis.commons.internal.debug.xray.XrayUi;
-import org.apache.isis.core.metamodel.spec.ManagedObject;
-import org.apache.isis.core.metamodel.spec.ManagedObjects;
-import org.apache.isis.core.security.util.XrayUtil;
-
-import lombok.val;
-
-final class _Xray {
-
-    public static void publish(
-            final EntityChangeTrackerJdo entityChangeTrackerDefault,
-            final Provider<InteractionProvider> interactionProviderProvider) {
-
-        if(!XrayUi.isXrayEnabled()) {
-            return;
-        }
-
-        final long propertyChangeRecordCount = entityChangeTrackerDefault.countPotentialPropertyChangeRecords();
-
-        val enteringLabel = String.format("consider %d entity change records for publishing",
-                propertyChangeRecordCount);
-
-        XrayUtil.createSequenceHandle(interactionProviderProvider.get(), "ec-tracker")
-        .ifPresent(handle->{
-
-            handle.submit(sequenceData->{
-
-                sequenceData.alias("ec-tracker", "EntityChange-\nTracker-\n(Default)");
-
-                if(propertyChangeRecordCount==0) {
-                    sequenceData.setConnectionArrowColor(Color.GRAY);
-                    sequenceData.setConnectionLabelColor(Color.GRAY);
-                }
-
-                val callee = handle.getCallees().getFirstOrFail();
-                sequenceData.enter(handle.getCaller(), callee, enteringLabel);
-                //sequenceData.activate(callee);
-            });
-
-        });
-    }
-
-    public static void enlistCreated(
-            final ManagedObject entity,
-            final Provider<InteractionProvider> interactionProviderProvider) {
-        addSequence("enlistCreated", entity, interactionProviderProvider);
-    }
-
-    public static void enlistDeleting(
-            final ManagedObject entity,
-            final Provider<InteractionProvider> interactionProviderProvider) {
-        addSequence("enlistDeleting", entity, interactionProviderProvider);
-    }
-
-    public static void enlistUpdating(
-            final ManagedObject entity,
-            final Provider<InteractionProvider> interactionProviderProvider) {
-        addSequence("enlistUpdating", entity, interactionProviderProvider);
-    }
-
-    public static void recognizeLoaded(
-            final ManagedObject entity,
-            final Provider<InteractionProvider> interactionProviderProvider) {
-        addSequence("recognizeLoaded", entity, interactionProviderProvider);
-    }
-
-    public static void recognizePersisting(
-            final ManagedObject entity,
-            final Provider<InteractionProvider> interactionProviderProvider) {
-        addSequence("recognizePersisting", entity, interactionProviderProvider);
-    }
-
-    public static void recognizeUpdating(
-            final ManagedObject entity,
-            final Provider<InteractionProvider> interactionProviderProvider) {
-        addSequence("recognizeUpdating", entity, interactionProviderProvider);
-    }
-
-    // -- HELPER
-
-    private static void addSequence(
-            final String what,
-            final ManagedObject entity,
-            final Provider<InteractionProvider> interactionProviderProvider) {
-
-        if(!XrayUi.isXrayEnabled()) {
-            return;
-        }
-
-        val enteringLabel = String.format("%s %s",
-                what,
-                ManagedObjects.isNullOrUnspecifiedOrEmpty(entity)
-                    ? "<empty>"
-                    : String.format("%s:\n%s",
-                            entity.getSpecification().getLogicalTypeName(),
-                            "" + entity.getPojo()));
-
-        _XrayEvent.event(enteringLabel);
-
-        XrayUtil.createSequenceHandle(interactionProviderProvider.get(), "ec-tracker")
-        .ifPresent(handle->{
-
-            handle.submit(sequenceData->{
-
-                sequenceData.alias("ec-tracker", "EntityChange-\nTracker-\n(Default)");
-
-                val callee = handle.getCallees().getFirstOrFail();
-                sequenceData.enter(handle.getCaller(), callee, enteringLabel);
-                //sequenceData.activate(callee);
-            });
-
-        });
-
-    }
-
-
-
-
-}
diff --git a/persistence/jpa/integration/pom.xml b/persistence/jpa/integration/pom.xml
index 05a9097765..00f1975201 100644
--- a/persistence/jpa/integration/pom.xml
+++ b/persistence/jpa/integration/pom.xml
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- 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 
+<!-- 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. -->
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
@@ -68,16 +68,21 @@
 
 	<dependencies>
 
-		<dependency>
-			<groupId>org.apache.isis.persistence</groupId>
-			<artifactId>isis-persistence-jpa-metamodel</artifactId>
-		</dependency>
-		
 		<dependency>
 			<groupId>org.apache.isis.core</groupId>
 			<artifactId>isis-core-runtime</artifactId>
 		</dependency>
-		
+
+        <dependency>
+            <groupId>org.apache.isis.persistence</groupId>
+            <artifactId>isis-persistence-commons</artifactId>
+        </dependency>
+
+		<dependency>
+			<groupId>org.apache.isis.persistence</groupId>
+			<artifactId>isis-persistence-jpa-metamodel</artifactId>
+		</dependency>
+
 		<dependency>
 			<groupId>org.springframework.data</groupId>
 			<artifactId>spring-data-jpa</artifactId>
@@ -96,14 +101,14 @@
 		</dependency>
 
 		<!-- TESTING -->
-		
+
         <dependency>
             <groupId>org.apache.isis.core</groupId>
             <artifactId>isis-core-internaltestsupport</artifactId>
             <scope>test</scope>
         </dependency>
 
-	</dependencies>
+    </dependencies>
 
 
-</project>
\ No newline at end of file
+</project>
diff --git a/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/IsisModulePersistenceJpaIntegration.java b/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/IsisModulePersistenceJpaIntegration.java
index 6989843f23..48b07bccb4 100644
--- a/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/IsisModulePersistenceJpaIntegration.java
+++ b/persistence/jpa/integration/src/main/java/org/apache/isis/persistence/jpa/integration/IsisModulePersistenceJpaIntegration.java
@@ -23,7 +23,7 @@ import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Import;
 
 import org.apache.isis.core.runtime.IsisModuleCoreRuntime;
-import org.apache.isis.persistence.jpa.integration.changetracking.EntityChangeTrackerJpa;
+import org.apache.isis.persistence.commons.IsisModulePersistenceCommons;
 import org.apache.isis.persistence.jpa.integration.entity.JpaEntityIntegration;
 import org.apache.isis.persistence.jpa.integration.services.JpaSupportServiceUsingSpring;
 import org.apache.isis.persistence.jpa.integration.typeconverters.applib.IsisBookmarkConverter;
@@ -45,6 +45,7 @@ import org.apache.isis.persistence.jpa.metamodel.IsisModulePersistenceJpaMetamod
 @Import({
         // modules
         IsisModuleCoreRuntime.class,
+        IsisModulePersistenceCommons.class,
         IsisModulePersistenceJpaMetamodel.class,
 
         // @Component's
@@ -52,7 +53,6 @@ import org.apache.isis.persistence.jpa.metamodel.IsisModulePersistenceJpaMetamod
 
         // @Service's
         JpaSupportServiceUsingSpring.class,
-        EntityChangeTrackerJpa.class,
 
 })
 @EntityScan(basePackageClasses = {