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 2020/12/30 18:51:44 UTC
[isis] 01/01: ISIS-2033: Let Spring take over Transaction Management
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch 2033-Spring_Data_Integration
in repository https://gitbox.apache.org/repos/asf/isis.git
commit e7f6276e5343e3c2117b8b9b25aad1a766dab3e3
Author: Andi Huber <ah...@apache.org>
AuthorDate: Wed Dec 30 19:51:21 2020 +0100
ISIS-2033: Let Spring take over Transaction Management
---
.../applib/services/xactn/TransactionService.java | 1 -
.../services/xactn/TransactionalProcessor.java | 42 ++++-
.../metamodel/context/HasMetaModelContext.java | 5 -
.../core/metamodel/context/MetaModelContext.java | 3 -
.../context/MetaModelContext_usingIoc.java | 9 +-
...ctionInvocationFacetForDomainEventAbstract.java | 52 +++---
...tySetterOrClearFacetForDomainEventAbstract.java | 2 +-
.../query/ObjectBulkLoader_builtinHandlers.java | 2 +-
.../command/CommandExecutorServiceDefault.java | 2 +-
.../wrapper/WrapperFactoryDefault.java | 2 +-
.../xactn/TransactionServiceSpring.java | 197 +++++++++++----------
.../xactn/_GlobalPlatformTransactionManager.java | 62 -------
.../jobcallables/IsTickingClockInitialized.java | 2 +-
.../jobcallables/ReplicateAndRunCommands.java | 12 +-
.../jdo/datanucleus/config/DnSettings.java | 74 ++++++++
persistence/jdo/integration/pom.xml | 4 +
.../jdo/integration/IsisModuleJdoIntegration.java | 26 ++-
.../lifecycles/JdoPersistenceLifecycleService.java | 14 +-
.../metamodel/facets/entity/JdoEntityFacet.java | 10 +-
.../jdo/integration/persistence/DnApplication.java | 77 ++++++++
.../persistence/JdoPersistenceSession5.java | 32 ++--
.../persistence/JdoPersistenceSessionFactory.java | 8 -
.../persistence/JdoPersistenceSessionFactory5.java | 148 +---------------
.../jdo/integration/persistence/_ContextUtil.java | 57 ------
...ponents5.java => _DnApplicationComponents.java} | 19 +-
...reManagerType.java => _DnStoreManagerType.java} | 10 +-
...sisPlatformTransactionManagerForJdoNoMore.java} | 29 ++-
.../transaction/TxManagerInternalFactory.java | 2 +-
.../jdo/integration/transaction/_TxProcessor.java | 13 +-
.../jdo/lightweight/IsisModuleJdoLightweight.java | 12 +-
.../metamodel/facets/entity/JdoEntityFacet.java | 25 +--
.../facets/entity/JdoEntityFacetFactory.java | 110 ------------
.../applayer/ApplicationLayerTestFactory.java | 2 +-
.../persistence/jpa/JpaBootstrappingTest.java | 20 ++-
...actionRollbackTest_usingTransactionService.java | 4 +-
...TransactionRollbackTest_usingTransactional.java | 56 ++++--
.../isis/JdoIsisTransactionScopeListenerTest.java | 2 +-
...actionRollbackTest_usingTransactionService.java | 55 +++---
...TransactionRollbackTest_usingTransactional.java | 64 ++++---
.../JdoSpringTransactionScopeListenerTest.java | 2 +-
...actionRollbackTest_usingTransactionService.java | 78 ++++----
...TransactionRollbackTest_usingTransactional.java | 23 ++-
.../jpa/JpaTransactionScopeListenerTest.java | 2 +-
.../applib/fixturescripts/FixtureScripts.java | 4 +-
.../applib/IsisInteractionHandler.java | 11 ++
.../IsisRestfulObjectsInteractionFilter.java | 15 +-
.../ui/pages/accmngt/register/RegisterPanel.java | 2 +-
47 files changed, 650 insertions(+), 753 deletions(-)
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionService.java b/api/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionService.java
index 736d145..d95bc42 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionService.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionService.java
@@ -56,5 +56,4 @@ public interface TransactionService extends TransactionalProcessor {
*/
void nextTransaction();
-
}
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionalProcessor.java b/api/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionalProcessor.java
index 64b4ebb..aab6bcf 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionalProcessor.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionalProcessor.java
@@ -20,20 +20,49 @@ package org.apache.isis.applib.services.xactn;
import java.util.concurrent.Callable;
+import org.springframework.transaction.TransactionDefinition;
+import org.springframework.transaction.support.DefaultTransactionDefinition;
+
import org.apache.isis.commons.functional.Result;
import org.apache.isis.commons.functional.ThrowingRunnable;
import lombok.val;
public interface TransactionalProcessor {
+
+ // -- INTERFACE
+
+ /**
+ * Runs given {@code callable} with a transactional boundary, where the detailed transactional behavior
+ * is governed by given {@link TransactionDefinition} {@code def}.
+ * @return {@link Result} of calling given {@code callable}
+ */
+ <T> Result<T> callTransactional(TransactionDefinition def, Callable<T> callable);
+
+ // -- SHORTCUTS
+
+ /**
+ * Runs given {@code runnable} with a transactional boundary, where the detailed transactional behavior
+ * is governed by given {@link TransactionDefinition} {@code def}.
+ */
+ default Result<Void> runTransactional(TransactionDefinition def, ThrowingRunnable runnable) {
+ return callTransactional(def, ThrowingRunnable.toCallable(runnable));
+ }
/**
* Runs given {@code callable} within an existing transactional boundary, or in the absence of such a
- * boundary creates a new one.
- *
+ * boundary, creates a new one.
+ * <p>
+ * In other words, support a current transaction, create a new one if none exists.
+ * @param <T>
* @param callable
+ * @return {@link Result} of calling given {@code callable}
*/
- <T> Result<T> executeWithinTransaction(Callable<T> callable);
+ default <T> Result<T> callWithinCurrentTransactionElseCreateNew(Callable<T> callable) {
+ val def = new DefaultTransactionDefinition();
+ def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
+ return callTransactional(def, callable);
+ }
/**
* Runs given {@code runnable} within an existing transactional boundary, or in the absence of such a
@@ -41,9 +70,10 @@ public interface TransactionalProcessor {
*
* @param runnable
*/
- default Result<Void> executeWithinTransaction(ThrowingRunnable runnable) {
- val callable = ThrowingRunnable.toCallable(runnable);
- return executeWithinTransaction(callable);
+ default Result<Void> runWithinCurrentTransactionElseCreateNew(ThrowingRunnable runnable) {
+ return callWithinCurrentTransactionElseCreateNew(ThrowingRunnable.toCallable(runnable));
}
+
+
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/context/HasMetaModelContext.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/context/HasMetaModelContext.java
index dfd56bf..f715482 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/context/HasMetaModelContext.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/context/HasMetaModelContext.java
@@ -28,7 +28,6 @@ import org.apache.isis.applib.services.repository.RepositoryService;
import org.apache.isis.applib.services.title.TitleService;
import org.apache.isis.applib.services.wrapper.WrapperFactory;
import org.apache.isis.applib.services.xactn.TransactionService;
-import org.apache.isis.applib.services.xactn.TransactionState;
import org.apache.isis.core.config.IsisConfiguration;
import org.apache.isis.core.config.environment.IsisSystemEnvironment;
import org.apache.isis.core.metamodel.execution.MemberExecutorService;
@@ -105,10 +104,6 @@ public interface HasMetaModelContext {
return getMetaModelContext().getRepositoryService();
}
- default TransactionState getTransactionState() {
- return getMetaModelContext().getTransactionState();
- }
-
default ManagedObject getHomePageAdapter() {
return getMetaModelContext().getHomePageAdapter();
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/context/MetaModelContext.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/context/MetaModelContext.java
index e9b36b3..caf3582 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/context/MetaModelContext.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/context/MetaModelContext.java
@@ -28,7 +28,6 @@ import org.apache.isis.applib.services.repository.RepositoryService;
import org.apache.isis.applib.services.title.TitleService;
import org.apache.isis.applib.services.wrapper.WrapperFactory;
import org.apache.isis.applib.services.xactn.TransactionService;
-import org.apache.isis.applib.services.xactn.TransactionState;
import org.apache.isis.core.config.IsisConfiguration;
import org.apache.isis.core.config.environment.IsisSystemEnvironment;
import org.apache.isis.core.metamodel.execution.MemberExecutorService;
@@ -90,8 +89,6 @@ public interface MetaModelContext {
TransactionService getTransactionService();
- TransactionState getTransactionState();
-
ManagedObject getHomePageAdapter();
Stream<ManagedObject> streamServiceAdapters();
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/context/MetaModelContext_usingIoc.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/context/MetaModelContext_usingIoc.java
index bf7ed11..cdae61e 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/context/MetaModelContext_usingIoc.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/context/MetaModelContext_usingIoc.java
@@ -32,7 +32,6 @@ import org.apache.isis.applib.services.repository.RepositoryService;
import org.apache.isis.applib.services.title.TitleService;
import org.apache.isis.applib.services.wrapper.WrapperFactory;
import org.apache.isis.applib.services.xactn.TransactionService;
-import org.apache.isis.applib.services.xactn.TransactionState;
import org.apache.isis.commons.internal.base._Lazy;
import org.apache.isis.commons.internal.exceptions._Exceptions;
import org.apache.isis.commons.internal.ioc._IocContainer;
@@ -128,10 +127,10 @@ class MetaModelContext_usingIoc implements MetaModelContext {
getSingletonElseFail(MemberExecutorService.class);
- @Override
- public final TransactionState getTransactionState() {
- return getTransactionService().currentTransactionState();
- }
+// @Override
+// public final TransactionState getTransactionState() {
+// return getTransactionService().currentTransactionState();
+// }
@Override
public final ManagedObject getHomePageAdapter() {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java
index aa9c4c7..632a5e5 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java
@@ -25,10 +25,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
-import java.util.function.Consumer;
-import org.apache.isis.applib.NonRecoverableException;
-import org.apache.isis.applib.RecoverableException;
import org.apache.isis.applib.events.domain.AbstractDomainEvent;
import org.apache.isis.applib.events.domain.ActionDomainEvent;
import org.apache.isis.applib.services.iactn.Interaction.ActionInvocation;
@@ -39,7 +36,6 @@ import org.apache.isis.commons.internal.assertions._Assert;
import org.apache.isis.commons.internal.base._Strings;
import org.apache.isis.commons.internal.collections._Arrays;
import org.apache.isis.core.metamodel.commons.CanonicalParameterUtil;
-import org.apache.isis.core.metamodel.commons.ThrowableExtensions;
import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
import org.apache.isis.core.metamodel.execution.InternalInteraction;
import org.apache.isis.core.metamodel.facetapi.FacetHolder;
@@ -57,6 +53,7 @@ import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
import lombok.Getter;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
+import lombok.SneakyThrows;
import lombok.val;
public abstract class ActionInvocationFacetForDomainEventAbstract
@@ -108,7 +105,7 @@ implements ImperativeFacet {
final InteractionInitiatedBy interactionInitiatedBy) {
val executionResult =
- getTransactionService().executeWithinTransaction(()->
+ getTransactionService().callWithinCurrentTransactionElseCreateNew(()->
doInvoke(owningAction, head, argumentAdapters, interactionInitiatedBy));
//PersistableTypeGuard.instate(executionResult);
@@ -231,10 +228,11 @@ implements ImperativeFacet {
private final ManagedObject mixinElseRegularAdapter;
private final ManagedObject mixedInAdapter;
+ @SneakyThrows
@Override
public Object execute(final ActionInvocation currentExecution) {
- try {
+// try {
// it's possible that an event handler changes these en-route
// so we take a non-final copy
Can<ManagedObject> argumentAdapters = this.argumentAdapters;
@@ -283,27 +281,27 @@ implements ImperativeFacet {
}
return UnwrapUtil.single(resultAdapterPossiblyCloned);
- } catch (Exception e) {
-
- final Consumer<RecoverableException> recovery = recoverableException->{
-
- if (!getTransactionState().canCommit()) {
- // something severe has happened to the underlying transaction;
- // so escalate this exception to be non-recoverable
- final Throwable recoverableExceptionCause = recoverableException.getCause();
- Throwable nonRecoverableCause = recoverableExceptionCause != null
- ? recoverableExceptionCause
- : recoverableException;
-
- // trim to first 300 chars
- final String message = trim(nonRecoverableCause.getMessage(), 300);
-
- throw new NonRecoverableException(message, nonRecoverableCause);
- }
- };
-
- return ThrowableExtensions.handleInvocationException(e, method.toString(), recovery);
- }
+// } catch (Exception e) {
+//
+// final Consumer<RecoverableException> recovery = recoverableException->{
+//
+// if (!getTransactionState().canCommit()) {
+// // something severe has happened to the underlying transaction;
+// // so escalate this exception to be non-recoverable
+// final Throwable recoverableExceptionCause = recoverableException.getCause();
+// Throwable nonRecoverableCause = recoverableExceptionCause != null
+// ? recoverableExceptionCause
+// : recoverableException;
+//
+// // trim to first 300 chars
+// final String message = trim(nonRecoverableCause.getMessage(), 300);
+//
+// throw new NonRecoverableException(message, nonRecoverableCause);
+// }
+// };
+//
+// return ThrowableExtensions.handleInvocationException(e, method.toString(), recovery);
+// }
}
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertySetterOrClearFacetForDomainEventAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertySetterOrClearFacetForDomainEventAbstract.java
index 5df5f23..e0a4f73 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertySetterOrClearFacetForDomainEventAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertySetterOrClearFacetForDomainEventAbstract.java
@@ -149,7 +149,7 @@ extends SingleValueFacetAbstract<Class<? extends PropertyDomainEvent<?,?>>> {
final InteractionInitiatedBy interactionInitiatedBy) {
return getTransactionService()
- .executeWithinTransaction(() ->
+ .callWithinCurrentTransactionElseCreateNew(() ->
doSetOrClearProperty(
style,
owningProperty,
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/query/ObjectBulkLoader_builtinHandlers.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/query/ObjectBulkLoader_builtinHandlers.java
index 9b73281..bb14a64 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/query/ObjectBulkLoader_builtinHandlers.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/query/ObjectBulkLoader_builtinHandlers.java
@@ -87,7 +87,7 @@ final class ObjectBulkLoader_builtinHandlers {
val entityFacet = spec.getFacet(EntityFacet.class);
if(entityFacet==null) {
throw _Exceptions.illegalArgument(
- "ObjectSpecification is missing an EntityFacet: %s", spec);
+ "ObjectSpecification is missing an EntityFacet: %s", spec.getCorrespondingClass());
}
val entities = entityFacet.fetchByQuery(spec, objectQuery.getQuery());
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandExecutorServiceDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandExecutorServiceDefault.java
index c6db66f..04a97b1 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandExecutorServiceDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/command/CommandExecutorServiceDefault.java
@@ -150,7 +150,7 @@ public class CommandExecutorServiceDefault implements CommandExecutorService {
copyStartedAtFromInteractionExecution(commandUpdater);
- val result = transactionService.executeWithinTransaction(
+ val result = transactionService.callWithinCurrentTransactionElseCreateNew(
() -> sudoPolicy == SudoPolicy.SWITCH
? sudoService.call(
context->context.withUser(UserMemento.ofName(dto.getUser())),
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/WrapperFactoryDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/WrapperFactoryDefault.java
index 0cc83ac..cabec81 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/WrapperFactoryDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/wrapper/WrapperFactoryDefault.java
@@ -578,7 +578,7 @@ public class WrapperFactoryDefault implements WrapperFactory {
val childCommand = interactionContextProvider.get().currentInteractionElseFail().getCommand();
childCommand.updater().setParent(parentCommand);
return transactionService
- .executeWithinTransaction(() -> {
+ .callWithinCurrentTransactionElseCreateNew(() -> {
val bookmark = commandExecutorService.executeCommand(commandDto, CommandOutcomeHandler.NULL);
if (bookmark == null) {
return null;
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/xactn/TransactionServiceSpring.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/xactn/TransactionServiceSpring.java
index 7edef00..30ef4a4 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/xactn/TransactionServiceSpring.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/xactn/TransactionServiceSpring.java
@@ -16,13 +16,12 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.apache.isis.core.runtimeservices.xactn;
import java.util.List;
+import java.util.Optional;
import java.util.concurrent.Callable;
-import javax.annotation.Nonnull;
import javax.inject.Inject;
import javax.inject.Named;
@@ -31,8 +30,9 @@ import org.springframework.context.annotation.Primary;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
-import org.springframework.transaction.support.TransactionCallback;
+import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.transaction.support.TransactionTemplate;
import org.apache.isis.applib.annotation.OrderPrecedence;
@@ -41,12 +41,9 @@ import org.apache.isis.applib.services.xactn.TransactionService;
import org.apache.isis.applib.services.xactn.TransactionState;
import org.apache.isis.commons.collections.Can;
import org.apache.isis.commons.functional.Result;
+import org.apache.isis.commons.internal.assertions._Assert;
import org.apache.isis.commons.internal.exceptions._Exceptions;
-import org.apache.isis.core.transaction.integration.IsisTransactionAspectSupport;
-import org.apache.isis.core.transaction.integration.IsisTransactionObject;
-import lombok.NonNull;
-import lombok.SneakyThrows;
import lombok.val;
import lombok.extern.log4j.Log4j2;
@@ -58,129 +55,139 @@ import lombok.extern.log4j.Log4j2;
@Log4j2
public class TransactionServiceSpring implements TransactionService {
- private final PlatformTransactionManager platformTransactionManager;
-
- // single TransactionTemplate shared amongst all methods in this instance
- private final TransactionTemplate transactionTemplate;
+ private final Can<PlatformTransactionManager> platformTransactionManagers;
@Inject
public TransactionServiceSpring(List<PlatformTransactionManager> platformTransactionManagers) {
- this.platformTransactionManager =
- _GlobalPlatformTransactionManager.of(Can.ofCollection(platformTransactionManagers));
-
- log.info("platformTransactionManagers: {}", platformTransactionManager);
-
- this.transactionTemplate = new TransactionTemplate(platformTransactionManager);
+ this.platformTransactionManagers = Can.ofCollection(platformTransactionManagers);
+ log.info("PlatformTransactionManagers: {}", platformTransactionManagers);
}
+ // -- SPRING INTEGRATION
+
@Override
- public void flushTransaction() {
+ public <T> Result<T> callTransactional(TransactionDefinition def, Callable<T> callable) {
- val txObject = currentTransactionObject(WarnIfNonePolicy.IGNORE);
-
- if(txObject==null) {
- return;
- }
-
- log.debug("about to flush tx");
- txObject.flush();
- }
-
- @Override
- public TransactionId currentTransactionId() {
-
- val txObject = currentTransactionObject(WarnIfNonePolicy.IGNORE);
-
- if(txObject==null) {
- return null;
- }
-
- log.debug("about to get current tx-id");
- return txObject.getTransactionId();
- }
-
- @Override @Nonnull
- public TransactionState currentTransactionState() {
-
- val txObject = currentTransactionObject(WarnIfNonePolicy.IGNORE);
+ val txManager = transactionManagerForElseFail(def);
+
+ val tx = txManager.getTransaction(def);
- if(txObject==null || txObject.getCurrentTransaction()==null) {
- return TransactionState.NONE;
+ val result = Result.ofNullable(callable);
+
+ if(result.isFailure()) {
+ txManager.rollback(tx);
+ } else {
+ txManager.commit(tx);
}
- val state = txObject.getCurrentTransaction().getTransactionState();
- return state != null
- ? state
- : TransactionState.NONE;
+ return result;
}
-
+
@Override
public void nextTransaction() {
- val status = platformTransactionManager.getTransaction(transactionTemplate);
- if(status.isCompleted()) {
+
+ val txManager = singletonTransactionManagerElseFail();
+ val txTemplate = new TransactionTemplate(txManager);
+ txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
+
+ // either reuse existing or create new
+ val txStatus = txManager.getTransaction(txTemplate);
+ if(txStatus.isNewTransaction()) {
+ // we have created a new transaction, so we are done
return;
}
- if(status.isRollbackOnly()) {
- platformTransactionManager.rollback(status);
+ // we are reusing an exiting transaction, so end it and create a new one afterwards
+ if(txStatus.isRollbackOnly()) {
+ txManager.rollback(txStatus);
} else {
- platformTransactionManager.commit(status);
+ txManager.commit(txStatus);
}
// begins a new transaction
- platformTransactionManager.getTransaction(transactionTemplate);
+ val txStatus2 = txManager.getTransaction(txTemplate);
+ _Assert.assertTrue(txStatus2.isNewTransaction()); //XXX remove once known to be always correct
+ }
+
+ @Override
+ public void flushTransaction() {
+ log.debug("about to flush tx");
+ currentTransactionStatus()
+ .ifPresent(TransactionStatus::flush);
}
@Override
- public <T> Result<T> executeWithinTransaction(final @NonNull Callable<T> callable) {
+ public TransactionId currentTransactionId() {
+ System.err.println("currentTransactionId:" + currentTransactionStatus().getClass().getName());
+ return TransactionId.empty();
+ }
- return Result.ofNullable(()->{
+ @Override
+ public TransactionState currentTransactionState() {
+
+ return currentTransactionStatus()
+ .map(txStatus->{
+
+ if(txStatus.isNewTransaction()) {
+ return txStatus.isRollbackOnly()
+ ? TransactionState.MUST_ABORT
+ : TransactionState.IN_PROGRESS;
+ }
- if(currentTransactionState() != TransactionState.NONE) {
- val t = callable.call();
- flushTransaction();
- return t;
+ if(txStatus.isCompleted()) {
+ return txStatus.isRollbackOnly()
+ ? TransactionState.ABORTED
+ : TransactionState.COMMITTED;
}
- return executeWithinNewTransaction(callable);
+ throw _Exceptions.unexpectedCodeReach();
- });
+ })
+ .orElse(TransactionState.NONE);
}
-
+
// -- HELPER
-
- enum WarnIfNonePolicy {
- IGNORE,
- LOG
- }
-
- private <T> T executeWithinNewTransaction(Callable<T> callable) {
-
- return transactionTemplate.execute(new TransactionCallback<T>() {
- // the code in this method executes in a transactional context
- @SneakyThrows
- @Override
- public T doInTransaction(TransactionStatus status) {
- return callable.call();
+
+ private PlatformTransactionManager transactionManagerForElseFail(TransactionDefinition def) {
+ if(def instanceof TransactionTemplate) {
+ val txManager = ((TransactionTemplate)def).getTransactionManager();
+ if(txManager!=null) {
+ return txManager;
}
- });
+ }
+ return platformTransactionManagers.getSingleton()
+ .orElseThrow(()->
+ platformTransactionManagers.getCardinality().isMultiple()
+ ? _Exceptions.illegalState("Multiple PlatformTransactionManagers are configured, "
+ + "make sure a PlatformTransactionManager is provided via the TransactionTemplate argument.")
+ : _Exceptions.illegalState("Needs a PlatformTransactionManager."));
}
- private IsisTransactionObject currentTransactionObject(WarnIfNonePolicy warnIfNonePolicy) {
+ private PlatformTransactionManager singletonTransactionManagerElseFail() {
+ return platformTransactionManagers.getSingleton()
+ .orElseThrow(()->
+ platformTransactionManagers.getCardinality().isMultiple()
+ ? _Exceptions.illegalState("Multiple PlatformTransactionManagers are configured, "
+ + "cannot reason about which one to use.")
+ : _Exceptions.illegalState("Needs a PlatformTransactionManager."));
+ }
- val txObject = IsisTransactionAspectSupport.currentTransactionObject().orElse(null);
+ private Optional<TransactionStatus> currentTransactionStatus() {
+
+ val txManager = singletonTransactionManagerElseFail();
+ val txTemplate = new TransactionTemplate(txManager);
+ txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_MANDATORY);
- if(txObject==null) {
- if(warnIfNonePolicy == WarnIfNonePolicy.LOG) {
- log.warn("no current txStatus present");
- _Exceptions.dumpStackTrace(System.out, 0, 1000);
- }
- return null;
+ // not strictly required, but to prevent stack-trace creation later on
+ if(!TransactionSynchronizationManager.isActualTransactionActive()) {
+ return Optional.empty();
}
-
- return txObject;
-
+
+ // get current transaction else throw an exception
+ return Result.of(()->
+ //XXX creating stack-traces is expensive
+ txManager.getTransaction(txTemplate))
+ .value();
+
}
-
-
}
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/xactn/_GlobalPlatformTransactionManager.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/xactn/_GlobalPlatformTransactionManager.java
deleted file mode 100644
index ca1714f..0000000
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/xactn/_GlobalPlatformTransactionManager.java
+++ /dev/null
@@ -1,62 +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.core.runtimeservices.xactn;
-
-import java.util.stream.Collectors;
-
-import org.springframework.transaction.PlatformTransactionManager;
-import org.springframework.transaction.TransactionDefinition;
-import org.springframework.transaction.TransactionException;
-import org.springframework.transaction.TransactionStatus;
-
-import org.apache.isis.commons.collections.Can;
-
-import lombok.RequiredArgsConstructor;
-
-@RequiredArgsConstructor(staticName = "of")
-final class _GlobalPlatformTransactionManager implements PlatformTransactionManager {
-
- private final Can<PlatformTransactionManager> localPlatformTransactionManagers;
-
- @Override
- public TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
- return localPlatformTransactionManagers.getFirstOrFail().getTransaction(definition);
- }
-
- @Override
- public void commit(TransactionStatus status) throws TransactionException {
- localPlatformTransactionManagers.getFirstOrFail().commit(status);
- }
-
- @Override
- public void rollback(TransactionStatus status) throws TransactionException {
- localPlatformTransactionManagers.getFirstOrFail().rollback(status);
- }
-
- @Override
- public String toString() {
- return String.format("local PlatformTransactionManagers [%s]",
- localPlatformTransactionManagers
- .stream()
- .map(PlatformTransactionManager::getClass)
- .map(Class::getSimpleName)
- .collect(Collectors.joining(", ")));
- }
-
-}
diff --git a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/jobcallables/IsTickingClockInitialized.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/jobcallables/IsTickingClockInitialized.java
index 2390c2a..f31972e 100644
--- a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/jobcallables/IsTickingClockInitialized.java
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/jobcallables/IsTickingClockInitialized.java
@@ -34,7 +34,7 @@ public class IsTickingClockInitialized implements Callable<Boolean> {
@Override
public Boolean call() {
- return transactionService.executeWithinTransaction(
+ return transactionService.callWithinCurrentTransactionElseCreateNew(
() -> tickingClockService.isInitialized())
.nullableOrElseFail();
}
diff --git a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/jobcallables/ReplicateAndRunCommands.java b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/jobcallables/ReplicateAndRunCommands.java
index cb44473..cc40bd6 100644
--- a/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/jobcallables/ReplicateAndRunCommands.java
+++ b/extensions/core/command-replay/secondary/src/main/java/org/apache/isis/extensions/commandreplay/secondary/jobcallables/ReplicateAndRunCommands.java
@@ -107,7 +107,7 @@ public class ReplicateAndRunCommands implements Callable<SecondaryStatus> {
val commandDtos = commandFetcher.fetchCommand(hwm);
commandsToReplay = commandDtos.stream()
.map(dto ->
- transactionService.executeWithinTransaction(
+ transactionService.callWithinCurrentTransactionElseCreateNew(
() -> commandJdoRepository.saveForReplay(dto))
.nullableOrElseFail()
).collect(Collectors.toList());
@@ -147,7 +147,7 @@ public class ReplicateAndRunCommands implements Callable<SecondaryStatus> {
//
val parent = commandJdo;
val childCommands =
- transactionService.executeWithinTransaction(
+ transactionService.callWithinCurrentTransactionElseCreateNew(
() -> commandJdoRepository.findByParent(parent))
.nullableOrElseFail();
for (val childCommand : childCommands) {
@@ -164,13 +164,13 @@ public class ReplicateAndRunCommands implements Callable<SecondaryStatus> {
}
private ReplayState executeCommandInTranAndAnalyse(final CommandJdo commandJdo) {
- transactionService.executeWithinTransaction(
+ transactionService.runWithinCurrentTransactionElseCreateNew(
() -> {
commandExecutorService.executeCommand(
CommandExecutorService.SudoPolicy.SWITCH, commandJdo.getCommandDto(), commandJdo.outcomeHandler());
});
- transactionService.executeWithinTransaction(() -> {
+ transactionService.runWithinCurrentTransactionElseCreateNew(() -> {
analysisService.analyse(commandJdo);
});
@@ -180,7 +180,9 @@ public class ReplicateAndRunCommands implements Callable<SecondaryStatus> {
private boolean isRunning() {
return controller
- .map( control -> transactionService.executeWithinTransaction(control::getState).nullableOrElseFail())
+ .map( control -> transactionService
+ .callWithinCurrentTransactionElseCreateNew(control::getState)
+ .nullableOrElseFail())
.map(state -> state == ReplayCommandExecutionController.State.RUNNING)
// if no controller implementation provided, then just continue
.orElse(true);
diff --git a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/config/DnSettings.java b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/config/DnSettings.java
index 5b2a004..00a2b0f 100644
--- a/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/config/DnSettings.java
+++ b/persistence/jdo/datanucleus/src/main/java/org/apache/isis/persistence/jdo/datanucleus/config/DnSettings.java
@@ -18,17 +18,23 @@
*/
package org.apache.isis.persistence.jdo.datanucleus.config;
+import java.util.HashMap;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Named;
+import org.datanucleus.PropertyNames;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Primary;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
import org.apache.isis.applib.annotation.OrderPrecedence;
+import org.apache.isis.commons.internal.collections._Maps;
+
+import lombok.val;
+import lombok.extern.log4j.Log4j2;
/**
* @since 2.0
@@ -38,13 +44,81 @@ import org.apache.isis.applib.annotation.OrderPrecedence;
@Order(OrderPrecedence.EARLY)
@Primary
@Qualifier("Default")
+@Log4j2
public class DnSettings {
@Inject @Named("dn-settings")
private Map<String, String> dnSettings;
+ private final Object lock = new Object();
+ private boolean amended = false;
+
public Map<String, String> getAsMap() {
+ synchronized(lock) {
+ if(!amended) {
+ addDataNucleusPropertiesAsRequired();
+ amended = true;
+ }
+ }
return dnSettings;
}
+ public Map<String, Object> getAsProperties() {
+ return _Maps.mapValues(getAsMap(), HashMap::new, Object.class::cast);
+ }
+
+ // -- HELPER
+
+ private void addDataNucleusPropertiesAsRequired() {
+
+ val props = dnSettings;
+
+ String connectionFactoryName = (String) props.get(PropertyNames.PROPERTY_CONNECTION_FACTORY_NAME);
+ if(connectionFactoryName != null) {
+ String connectionFactory2Name = (String) props.get(PropertyNames.PROPERTY_CONNECTION_FACTORY2_NAME);
+ String transactionType = (String) props.get("javax.jdo.option.TransactionType");
+ // extended logging
+ if(transactionType == null) {
+ log.info("found config properties to use non-JTA JNDI datasource ({})", connectionFactoryName);
+ if(connectionFactory2Name != null) {
+ log.warn("found config properties to use non-JTA JNDI datasource ({}); second '-nontx' JNDI datasource also configured but will not be used ({})", connectionFactoryName, connectionFactory2Name);
+ }
+ } else {
+ log.info("found config properties to use JTA JNDI datasource ({})", connectionFactoryName);
+ }
+ if(connectionFactory2Name == null) {
+ // JDO/DN itself will (probably) throw an exception
+ log.error("found config properties to use JTA JNDI datasource ({}) but config properties for second '-nontx' JNDI datasource were *not* found", connectionFactoryName);
+ } else {
+ log.info("... and config properties for second '-nontx' JNDI datasource also found; {}", connectionFactory2Name);
+ }
+ // nothing further to do
+ } else {
+ // use JDBC connection properties; put if not present
+
+ putIfNotPresent(props, "javax.jdo.option.ConnectionDriverName", "org.hsqldb.jdbcDriver");
+ putIfNotPresent(props, "javax.jdo.option.ConnectionURL", "jdbc:hsqldb:mem:test");
+ putIfNotPresent(props, "javax.jdo.option.ConnectionUserName", "sa");
+ putIfNotPresent(props, "javax.jdo.option.ConnectionPassword", "");
+
+ if(log.isInfoEnabled()) {
+ log.info("using JDBC connection '{}'",
+ props.get("javax.jdo.option.ConnectionURL"));
+ }
+ }
+
+ }
+
+ private static void putIfNotPresent(
+ final Map<String, String> props,
+ final String key,
+ final String value) {
+
+ if(!props.containsKey(key)) {
+ props.put(key, value);
+ }
+ }
+
+
+
}
diff --git a/persistence/jdo/integration/pom.xml b/persistence/jdo/integration/pom.xml
index bcf21eb..056fd4b 100644
--- a/persistence/jdo/integration/pom.xml
+++ b/persistence/jdo/integration/pom.xml
@@ -68,6 +68,10 @@
<artifactId>isis-persistence-jdo-datanucleus</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.isis.persistence</groupId>
+ <artifactId>isis-persistence-jdo-spring</artifactId>
+ </dependency>
<!-- TESTING -->
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 2ef182f..b66820e 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
@@ -18,18 +18,25 @@
*/
package org.apache.isis.persistence.jdo.integration;
+import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
+import org.springframework.context.annotation.Primary;
+import org.apache.isis.core.metamodel.context.MetaModelContext;
import org.apache.isis.core.runtime.IsisModuleCoreRuntime;
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.jdosupport.IsisJdoSupportDN5;
import org.apache.isis.persistence.jdo.integration.lifecycles.JdoPersistenceLifecycleService;
import org.apache.isis.persistence.jdo.integration.metamodel.JdoIntegrationProgrammingModel;
import org.apache.isis.persistence.jdo.integration.persistence.JdoPersistenceSessionFactory5;
-import org.apache.isis.persistence.jdo.integration.transaction.IsisPlatformTransactionManagerForJdo;
import org.apache.isis.persistence.jdo.metamodel.IsisModuleJdoMetamodel;
+import org.apache.isis.persistence.jdo.spring.integration.JdoTransactionManager;
+import org.apache.isis.persistence.jdo.spring.integration.LocalPersistenceManagerFactoryBean;
+
+import lombok.val;
@Configuration
@Import({
@@ -43,11 +50,26 @@ import org.apache.isis.persistence.jdo.metamodel.IsisModuleJdoMetamodel;
JdoIntegrationProgrammingModel.class,
IsisJdoSupportDN5.class,
- IsisPlatformTransactionManagerForJdo.class,
+ //IsisPlatformTransactionManagerForJdo.class,
JdoPersistenceLifecycleService.class,
JdoPersistenceSessionFactory5.class,
})
public class IsisModuleJdoIntegration {
+ @Bean
+ public LocalPersistenceManagerFactoryBean getLocalPersistenceManagerFactoryBean(
+ final MetaModelContext metaModelContext,
+ final DnSettings dnSettings) {
+
+ val lpmfBean = new LocalPersistenceManagerFactoryBean();
+ lpmfBean.setJdoPropertyMap(dnSettings.getAsProperties());
+ return lpmfBean;
+ }
+
+ @Bean @Primary
+ public JdoTransactionManager getJdoTransactionManager(LocalPersistenceManagerFactoryBean localPmfBean) {
+ return new JdoTransactionManager(localPmfBean.getObject());
+ }
+
}
diff --git a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/lifecycles/JdoPersistenceLifecycleService.java b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/lifecycles/JdoPersistenceLifecycleService.java
index 8dd8866..67a376b 100644
--- a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/lifecycles/JdoPersistenceLifecycleService.java
+++ b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/lifecycles/JdoPersistenceLifecycleService.java
@@ -37,6 +37,8 @@ import org.apache.isis.core.interaction.events.IsisInteractionLifecycleEvent;
import org.apache.isis.core.interaction.session.InteractionSession;
import org.apache.isis.core.metamodel.context.MetaModelContext;
import org.apache.isis.core.runtime.events.AppLifecycleEvent;
+import org.apache.isis.persistence.jdo.datanucleus.config.DnSettings;
+import org.apache.isis.persistence.jdo.integration.persistence.DnApplication;
import org.apache.isis.persistence.jdo.integration.persistence.JdoPersistenceSession;
import org.apache.isis.persistence.jdo.integration.persistence.JdoPersistenceSessionFactory;
@@ -54,6 +56,7 @@ public class JdoPersistenceLifecycleService {
@Inject MetaModelContext metaModelContext;
@Inject JdoPersistenceSessionFactory persistenceSessionFactory;
@Inject IsisBeanTypeRegistry isisBeanTypeRegistry;
+ @Inject DnSettings dnSettings;
@PostConstruct
public void postConstr() {
@@ -70,10 +73,9 @@ public class JdoPersistenceLifecycleService {
switch (event) {
case PRE_METAMODEL:
- create();
break;
case POST_METAMODEL:
- init();
+ new DnApplication(metaModelContext, dnSettings); // creates schema
break;
default:
@@ -124,14 +126,6 @@ public class JdoPersistenceLifecycleService {
return Optional.ofNullable(interactionSession)
.map(session->session.getAttribute(JdoPersistenceSession.class));
}
-
- private void create() {
- persistenceSessionFactory.init(metaModelContext);
- }
-
- private void init() {
- persistenceSessionFactory.catalogNamedQueries();
- }
}
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 1758b9c..9ef26ec 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
@@ -245,7 +245,7 @@ implements EntityFacet {
log.debug("about to persist entity {}", pojo);
getTransactionalProcessor()
- .executeWithinTransaction(()->{pm.makePersistent(pojo);})
+ .runWithinCurrentTransactionElseCreateNew(()->pm.makePersistent(pojo))
.nullableOrElseFail();
//TODO integrate with entity change tracking
@@ -267,7 +267,7 @@ implements EntityFacet {
log.debug("about to delete entity {}", pojo);
getTransactionalProcessor()
- .executeWithinTransaction(()->{pm.deletePersistent(pojo);})
+ .runWithinCurrentTransactionElseCreateNew(()->pm.deletePersistent(pojo))
.nullableOrElseFail();
//TODO integrate with entity change tracking
@@ -287,7 +287,7 @@ implements EntityFacet {
log.debug("about to refresh entity {}", pojo);
getTransactionalProcessor()
- .executeWithinTransaction(()->{pm.refresh(pojo);})
+ .runWithinCurrentTransactionElseCreateNew(()->pm.refresh(pojo))
.nullableOrElseFail();
//TODO integrate with entity change tracking
@@ -337,14 +337,14 @@ implements EntityFacet {
private JdoPersistenceSession getJdoPersistenceSession() {
return isisInteractionTrackerLazy.get().currentInteractionSession()
.map(interactionSession->interactionSession.getAttribute(JdoPersistenceSession.class))
- .orElse(null);
+ .orElseThrow(()->_Exceptions.illegalState("no JdoPersistenceSession on current thread"));
}
// -- HELPER
private Can<ManagedObject> fetchWithinTransaction(Supplier<List<?>> fetcher) {
val fetchResultHandler = getFetchResultHandler();
- return getTransactionalProcessor().executeWithinTransaction(
+ return getTransactionalProcessor().callWithinCurrentTransactionElseCreateNew(
()->_NullSafe.stream(fetcher.get())
.map(fetchedObject->adopt(fetchResultHandler, fetchedObject))
.collect(Can.toCan()))
diff --git a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/DnApplication.java b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/DnApplication.java
new file mode 100644
index 0000000..29e8b7b
--- /dev/null
+++ b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/DnApplication.java
@@ -0,0 +1,77 @@
+/*
+ * 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.persistence;
+
+import org.apache.isis.commons.internal.base._NullSafe;
+import org.apache.isis.core.config.beans.IsisBeanTypeRegistry;
+import org.apache.isis.core.metamodel.context.MetaModelContext;
+import org.apache.isis.persistence.jdo.datanucleus.config.DnSettings;
+import org.apache.isis.persistence.jdo.integration.config.JdoEntityTypeRegistry;
+
+import lombok.val;
+import lombok.extern.log4j.Log4j2;
+
+@Log4j2
+public class DnApplication {
+
+ private _DnApplicationComponents dnApplicationComponents;
+ private final JdoEntityTypeRegistry jdoEntityTypeRegistry = new JdoEntityTypeRegistry();
+
+ public DnApplication(
+ final MetaModelContext metaModelContext,
+ final DnSettings dnSettings) {
+
+ dnApplicationComponents = createDataNucleusApplicationComponents(
+ metaModelContext,
+ dnSettings);
+ }
+
+ public void shutdown() {
+ dnApplicationComponents.shutdown();
+ }
+
+ // -- HELPER
+
+ private _DnApplicationComponents createDataNucleusApplicationComponents(
+ final MetaModelContext metaModelContext,
+ final DnSettings dnSettings) {
+
+ val configuration = metaModelContext.getConfiguration();
+ val isisBeanTypeRegistry = metaModelContext.getServiceRegistry()
+ .lookupServiceElseFail(IsisBeanTypeRegistry.class);
+
+ val classesToBePersisted = jdoEntityTypeRegistry.getEntityTypes(isisBeanTypeRegistry);
+
+ if(log.isDebugEnabled()) {
+ log.debug("Entity types discovered:");
+ _NullSafe.stream(classesToBePersisted)
+ .forEach(entityClassName->log.debug(" - {}", entityClassName));
+ }
+
+ val dataNucleusApplicationComponents = new _DnApplicationComponents(
+ configuration,
+ dnSettings.getAsProperties(),
+ classesToBePersisted);
+
+ _DnApplicationComponents.catalogNamedQueries(metaModelContext, classesToBePersisted);
+
+ return dataNucleusApplicationComponents;
+ }
+
+}
diff --git a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/JdoPersistenceSession5.java b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/JdoPersistenceSession5.java
index c47c051..7b1f2ae 100644
--- a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/JdoPersistenceSession5.java
+++ b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/JdoPersistenceSession5.java
@@ -28,7 +28,6 @@ import org.apache.isis.core.transaction.changetracking.EntityChangeTracker;
import org.apache.isis.persistence.jdo.integration.lifecycles.IsisLifecycleListener;
import org.apache.isis.persistence.jdo.integration.lifecycles.JdoStoreLifecycleListenerForIsis;
import org.apache.isis.persistence.jdo.integration.lifecycles.LoadLifecycleListenerForIsis;
-import org.apache.isis.persistence.jdo.integration.transaction.TxManagerInternalFactory;
import lombok.Getter;
import lombok.val;
@@ -49,7 +48,7 @@ implements
@Getter(onMethod_ = {@Override}) private final MetaModelContext metaModelContext;
@Getter(onMethod_ = {@Override}) private FetchResultHandler fetchResultHandler;
- private final PersistenceManagerFactory jdoPersistenceManagerFactory;
+ private final PersistenceManagerFactory pmf;
private Runnable unregisterLifecycleListeners;
// -- CONSTRUCTOR
@@ -57,23 +56,22 @@ implements
/**
* Initialize the object store so that calls to this object store access
* persisted objects and persist changes to the object that are saved.
+ * @param pmf
*/
public JdoPersistenceSession5(
- final MetaModelContext metaModelContext,
- final PersistenceManagerFactory jdoPersistenceManagerFactory) {
+ final MetaModelContext metaModelContext,
+ final PersistenceManagerFactory pmf) {
if (log.isDebugEnabled()) {
log.debug("creating {}", this);
}
this.metaModelContext = metaModelContext;
- this.jdoPersistenceManagerFactory = jdoPersistenceManagerFactory;
+ this.pmf = pmf;
// sub-components
- this.transactionalProcessor = TxManagerInternalFactory.newTransactionalProcessor(
- metaModelContext,
- this);
-
+ this.transactionalProcessor = metaModelContext.getTransactionService();
+
this.state = State.NOT_INITIALIZED;
}
@@ -102,7 +100,6 @@ implements
// -- OPEN
-
@Override
public void open() {
state.ensureNotOpened();
@@ -111,8 +108,8 @@ implements
log.debug("opening {}", this);
}
- persistenceManager = jdoPersistenceManagerFactory.getPersistenceManager();
-
+ this.persistenceManager = pmf.getPersistenceManager();
+
val entityChangeTracker = metaModelContext.getServiceRegistry()
.lookupServiceElseFail(EntityChangeTracker.class);
@@ -158,6 +155,17 @@ implements
unregisterLifecycleListeners = null;
try {
+
+// if (!participate) {
+//
+// val pmf = pmf;
+//
+// PersistenceManagerHolder pmHolder = (PersistenceManagerHolder)
+// TransactionSynchronizationManager.unbindResource(pmf);
+// log.debug("Closing JDO PersistenceManager in PersistenceSession");
+// PersistenceManagerFactoryUtils.releasePersistenceManager(pmHolder.getPersistenceManager(), pmf);
+// }
+
persistenceManager.close();
} catch(final Throwable ex) {
// ignore
diff --git a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/JdoPersistenceSessionFactory.java b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/JdoPersistenceSessionFactory.java
index f1c4e28..8284e15 100644
--- a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/JdoPersistenceSessionFactory.java
+++ b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/JdoPersistenceSessionFactory.java
@@ -18,16 +18,8 @@
*/
package org.apache.isis.persistence.jdo.integration.persistence;
-import org.apache.isis.core.metamodel.context.MetaModelContext;
-
public interface JdoPersistenceSessionFactory {
JdoPersistenceSession createPersistenceSession();
- void init(MetaModelContext metaModelContext);
-
- void catalogNamedQueries();
-
- boolean isInitialized();
-
}
diff --git a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/JdoPersistenceSessionFactory5.java b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/JdoPersistenceSessionFactory5.java
index a73aee3..20acebe 100644
--- a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/JdoPersistenceSessionFactory5.java
+++ b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/JdoPersistenceSessionFactory5.java
@@ -16,36 +16,22 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.apache.isis.persistence.jdo.integration.persistence;
-import java.util.Map;
import java.util.Objects;
-import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
-import org.datanucleus.PropertyNames;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Primary;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
import org.apache.isis.applib.annotation.OrderPrecedence;
-import org.apache.isis.commons.internal.base._Blackhole;
-import org.apache.isis.commons.internal.base._Lazy;
-import org.apache.isis.commons.internal.base._NullSafe;
-import org.apache.isis.commons.internal.collections._Maps;
-import org.apache.isis.core.config.IsisConfiguration;
-import org.apache.isis.core.config.beans.IsisBeanTypeRegistry;
import org.apache.isis.core.metamodel.context.MetaModelContext;
-import org.apache.isis.persistence.jdo.datanucleus.config.DnSettings;
-import org.apache.isis.persistence.jdo.integration.config.JdoEntityTypeRegistry;
-
-import lombok.val;
-import lombok.extern.log4j.Log4j2;
+import org.apache.isis.persistence.jdo.spring.integration.LocalPersistenceManagerFactoryBean;
/**
*
@@ -58,142 +44,22 @@ import lombok.extern.log4j.Log4j2;
@Primary
@Qualifier("JdoDN5")
@Singleton
-@Log4j2
public class JdoPersistenceSessionFactory5
implements JdoPersistenceSessionFactory {
- @Inject private IsisBeanTypeRegistry isisBeanTypeRegistry;
-
- private final _Lazy<_DataNucleusApplicationComponents5> applicationComponents =
- _Lazy.threadSafe(this::createDataNucleusApplicationComponents);
+ @Inject private LocalPersistenceManagerFactoryBean localPmfBean;
+ @Inject private MetaModelContext metaModelContext;
- private MetaModelContext metaModelContext;
- private IsisConfiguration configuration;
- private final JdoEntityTypeRegistry jdoEntityTypeRegistry = new JdoEntityTypeRegistry();
-
- @Override
- public void init(MetaModelContext metaModelContext) {
- this.metaModelContext = metaModelContext;
- this.configuration = metaModelContext.getConfiguration();
- // need to eagerly build, ... must be completed before catalogNamedQueries().
- // Why? because that method causes entity classes to be loaded which register with DN's EnhancementHelper,
- // which are then cached in DN. It results in our CreateSchema listener not firing.
- _Blackhole.consume(applicationComponents.get());
- }
-
-
- @Override
- public boolean isInitialized() {
- return this.configuration != null;
- }
-
- private _DataNucleusApplicationComponents5 createDataNucleusApplicationComponents() {
-
- val dnSettings = metaModelContext.getServiceRegistry().lookupServiceElseFail(DnSettings.class);
- val datanucleusProps = addDataNucleusPropertiesAsRequired(dnSettings);
- val classesToBePersisted = jdoEntityTypeRegistry.getEntityTypes(isisBeanTypeRegistry);
-
- val dataNucleusApplicationComponents = new _DataNucleusApplicationComponents5(
- configuration,
- datanucleusProps,
- classesToBePersisted);
-
- return dataNucleusApplicationComponents;
- }
-
- @Override
- public void catalogNamedQueries() {
- val classesToBePersisted = jdoEntityTypeRegistry.getEntityTypes(isisBeanTypeRegistry);
-
- if(log.isDebugEnabled()) {
- log.debug("Entity types discovered:");
- _NullSafe.stream(classesToBePersisted)
- .forEach(entityClassName->log.debug(" - {}", entityClassName));
- }
-
- _DataNucleusApplicationComponents5.catalogNamedQueries(classesToBePersisted,
- metaModelContext.getSpecificationLoader());
- }
-
- private Map<String, Object> addDataNucleusPropertiesAsRequired(DnSettings dnSettings) {
-
- val props = _Maps.<String, Object>newHashMap();
- props.putAll(dnSettings.getAsMap());
- _ContextUtil.putMetaModelContext(props, metaModelContext);
-
- String connectionFactoryName = (String) props.get(PropertyNames.PROPERTY_CONNECTION_FACTORY_NAME);
- if(connectionFactoryName != null) {
- String connectionFactory2Name = (String) props.get(PropertyNames.PROPERTY_CONNECTION_FACTORY2_NAME);
- String transactionType = (String) props.get("javax.jdo.option.TransactionType");
- // extended logging
- if(transactionType == null) {
- log.info("found config properties to use non-JTA JNDI datasource ({})", connectionFactoryName);
- if(connectionFactory2Name != null) {
- log.warn("found config properties to use non-JTA JNDI datasource ({}); second '-nontx' JNDI datasource also configured but will not be used ({})", connectionFactoryName, connectionFactory2Name);
- }
- } else {
- log.info("found config properties to use JTA JNDI datasource ({})", connectionFactoryName);
- }
- if(connectionFactory2Name == null) {
- // JDO/DN itself will (probably) throw an exception
- log.error("found config properties to use JTA JNDI datasource ({}) but config properties for second '-nontx' JNDI datasource were *not* found", connectionFactoryName);
- } else {
- log.info("... and config properties for second '-nontx' JNDI datasource also found; {}", connectionFactory2Name);
- }
- // nothing further to do
- } else {
- // use JDBC connection properties; put if not present
-
- putIfNotPresent(props, "javax.jdo.option.ConnectionDriverName", "org.hsqldb.jdbcDriver");
- putIfNotPresent(props, "javax.jdo.option.ConnectionURL", "jdbc:hsqldb:mem:test");
- putIfNotPresent(props, "javax.jdo.option.ConnectionUserName", "sa");
- putIfNotPresent(props, "javax.jdo.option.ConnectionPassword", "");
-
- if(log.isInfoEnabled()) {
- log.info("using JDBC connection '{}'",
- props.get("javax.jdo.option.ConnectionURL"));
- }
- }
-
- return props;
- }
-
- private static void putIfNotPresent(
- Map<String, Object> props,
- String key,
- String value) {
-
- if(!props.containsKey(key)) {
- props.put(key, value);
- }
- }
-
-
- @PreDestroy
- public final void shutdown() {
- if(!isInitialized()) {
- return;
- }
- if(applicationComponents.isMemoized()) {
- applicationComponents.get().shutdown();
- applicationComponents.clear();
- }
- this.configuration = null;
- }
-
@Override
public JdoPersistenceSession5 createPersistenceSession() {
- Objects.requireNonNull(applicationComponents.get(),
- () -> "PersistenceSession5 requires initialization. "+this.hashCode());
-
- val persistenceManagerFactory =
- applicationComponents.get().getPersistenceManagerFactory();
+ Objects.requireNonNull(localPmfBean,
+ () -> "PersistenceSessionFactory5 requires initialization. " + this.hashCode());
return new JdoPersistenceSession5(
metaModelContext,
- persistenceManagerFactory);
+ localPmfBean.getObject());
}
-
+
}
diff --git a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/_ContextUtil.java b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/_ContextUtil.java
deleted file mode 100644
index 05382b3..0000000
--- a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/_ContextUtil.java
+++ /dev/null
@@ -1,57 +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.persistence;
-
-import java.util.Map;
-import java.util.Optional;
-
-import org.datanucleus.ExecutionContext;
-
-import org.apache.isis.core.metamodel.context.MetaModelContext;
-
-import lombok.val;
-
-/**
- *
- * @since 2.0
- *
- */
-final class _ContextUtil {
-
- // required to be lower-case for DN to be accepted
- private static final String METAMODELCONTEXT_PROPERTY_KEY = "isis.metamodelcontext";
-
- public static void putMetaModelContext(
- Map<String, Object> map,
- MetaModelContext metaModelContext) {
-
- map.put(METAMODELCONTEXT_PROPERTY_KEY, metaModelContext);
- }
-
- public static Optional<MetaModelContext> extractMetaModelContext(ExecutionContext ec) {
-
- val metaModelContext = (MetaModelContext) ec.getNucleusContext()
- .getConfiguration()
- .getPersistenceProperties()
- .get(METAMODELCONTEXT_PROPERTY_KEY);
-
- return Optional.ofNullable(metaModelContext);
- }
-
-}
diff --git a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/_DataNucleusApplicationComponents5.java b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/_DnApplicationComponents.java
similarity index 95%
rename from persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/_DataNucleusApplicationComponents5.java
rename to persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/_DnApplicationComponents.java
index eb80c59..3a350b0 100644
--- a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/_DataNucleusApplicationComponents5.java
+++ b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/_DnApplicationComponents.java
@@ -18,6 +18,8 @@
*/
package org.apache.isis.persistence.jdo.integration.persistence;
+import static org.apache.isis.commons.internal.base._NullSafe.stream;
+
import java.util.Map;
import java.util.Properties;
import java.util.Set;
@@ -40,22 +42,20 @@ import org.apache.isis.commons.internal.collections._Maps;
import org.apache.isis.commons.internal.context._Context;
import org.apache.isis.commons.internal.factory._InstanceUtil;
import org.apache.isis.core.config.IsisConfiguration;
+import org.apache.isis.core.metamodel.context.MetaModelContext;
import org.apache.isis.core.metamodel.spec.ObjectSpecId;
-import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
import org.apache.isis.persistence.jdo.integration.config.DataNucleusPropertiesAware;
import org.apache.isis.persistence.jdo.integration.lifecycles.DataNucleusLifeCycleHelper;
import org.apache.isis.persistence.jdo.provider.metamodel.facets.object.query.JdoNamedQuery;
import org.apache.isis.persistence.jdo.provider.metamodel.facets.object.query.JdoQueryFacet;
-import static org.apache.isis.commons.internal.base._NullSafe.stream;
-
import lombok.Getter;
import lombok.val;
import lombok.extern.log4j.Log4j2;
@Vetoed
@Log4j2
-final class _DataNucleusApplicationComponents5 {
+final class _DnApplicationComponents {
private final Set<String> persistableClassNameSet;
private final IsisConfiguration configuration;
@@ -63,7 +63,7 @@ final class _DataNucleusApplicationComponents5 {
@Getter private PersistenceManagerFactory persistenceManagerFactory;
- public _DataNucleusApplicationComponents5(
+ public _DnApplicationComponents(
final IsisConfiguration configuration,
final Map<String, Object> datanucleusProps,
final Set<String> persistableClassNameSet) {
@@ -93,7 +93,6 @@ final class _DataNucleusApplicationComponents5 {
try {
// this is where DN will throw an exception if we pass it any config props it doesn't like the look of.
// we want to fail, but let's make sure that the error is visible to help the developer
-
return JDOHelper.getPersistenceManagerFactory(datanucleusProps, _Context.getDefaultClassLoader());
} catch(JDOUserException ex) {
log.fatal(ex);
@@ -106,7 +105,7 @@ final class _DataNucleusApplicationComponents5 {
final Set<String> persistableClassNameSet,
final Map<String, Object> datanucleusProps) {
- final _DNStoreManagerType dnStoreManagerType = _DNStoreManagerType.typeOf(datanucleusProps);
+ final _DnStoreManagerType dnStoreManagerType = _DnStoreManagerType.typeOf(datanucleusProps);
PersistenceManagerFactory persistenceManagerFactory;
@@ -224,11 +223,13 @@ final class _DataNucleusApplicationComponents5 {
}
static void catalogNamedQueries(
- Set<String> persistableClassNames, SpecificationLoader specificationLoader) {
+ final MetaModelContext metaModelContext,
+ final Set<String> persistableClassNames) {
val namedQueryByName = _Maps.<String, JdoNamedQuery>newHashMap();
for (val persistableClassName: persistableClassNames) {
- val spec = specificationLoader.loadSpecification(ObjectSpecId.of(persistableClassName));
+ val spec = metaModelContext.getSpecificationLoader()
+ .loadSpecification(ObjectSpecId.of(persistableClassName));
val jdoQueryFacet = spec.getFacet(JdoQueryFacet.class);
if (jdoQueryFacet == null) {
continue;
diff --git a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/_DNStoreManagerType.java b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/_DnStoreManagerType.java
similarity index 93%
rename from persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/_DNStoreManagerType.java
rename to persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/_DnStoreManagerType.java
index 9eea932..8ba0347 100644
--- a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/_DNStoreManagerType.java
+++ b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/persistence/_DnStoreManagerType.java
@@ -35,14 +35,14 @@ import org.datanucleus.store.schema.SchemaAwareStoreManager;
*
* @since 2.0.0-M2
*/
-enum _DNStoreManagerType {
+enum _DnStoreManagerType {
SchemaAware,
Federated, // [ahuber] not used by now
Other
;
- public static _DNStoreManagerType typeOf(Map<String, Object> datanucleusProps) {
+ public static _DnStoreManagerType typeOf(Map<String, Object> datanucleusProps) {
if(hasSecondaryDataStore(datanucleusProps)) {
return Federated;
@@ -108,14 +108,14 @@ enum _DNStoreManagerType {
return false;
}
- private static _DNStoreManagerType probe(
+ private static _DnStoreManagerType probe(
Map<String, Object> datanucleusProps,
- Function<StoreManager, _DNStoreManagerType> categorizer) {
+ Function<StoreManager, _DnStoreManagerType> categorizer) {
// we create a throw-away instance of PMF so that we can probe whether DN has
// been configured with a schema-aware store manager or not.
final JDOPersistenceManagerFactory probePmf = (JDOPersistenceManagerFactory)
- _DataNucleusApplicationComponents5.newPersistenceManagerFactory(datanucleusProps);
+ _DnApplicationComponents.newPersistenceManagerFactory(datanucleusProps);
try {
final PersistenceNucleusContext nucleusContext = probePmf.getNucleusContext();
diff --git a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/transaction/IsisPlatformTransactionManagerForJdo.java b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/transaction/IsisPlatformTransactionManagerForJdoNoMore.java
similarity index 87%
rename from persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/transaction/IsisPlatformTransactionManagerForJdo.java
rename to persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/transaction/IsisPlatformTransactionManagerForJdoNoMore.java
index f395a03..4d19bdd 100644
--- a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/transaction/IsisPlatformTransactionManagerForJdo.java
+++ b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/transaction/IsisPlatformTransactionManagerForJdoNoMore.java
@@ -18,19 +18,11 @@
*/
package org.apache.isis.persistence.jdo.integration.transaction;
-import javax.inject.Inject;
-import javax.inject.Named;
-
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.context.annotation.Primary;
-import org.springframework.core.annotation.Order;
-import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionException;
import org.springframework.transaction.support.AbstractPlatformTransactionManager;
import org.springframework.transaction.support.DefaultTransactionStatus;
-import org.apache.isis.applib.annotation.OrderPrecedence;
import org.apache.isis.applib.services.eventbus.EventBusService;
import org.apache.isis.commons.internal.context._Context;
import org.apache.isis.commons.internal.exceptions._Exceptions;
@@ -46,24 +38,23 @@ import org.apache.isis.core.transaction.integration.IsisTransactionAspectSupport
import org.apache.isis.core.transaction.integration.IsisTransactionObject;
import org.apache.isis.core.transaction.integration.IsisTransactionObject.IsisInteractionScopeType;
-import lombok.RequiredArgsConstructor;
import lombok.val;
import lombok.extern.log4j.Log4j2;
-@Service
-@Named("isisJdoDn5.IsisPlatformTransactionManagerForJdo")
-@Order(OrderPrecedence.MIDPOINT)
-@Primary
-@Qualifier("JdoDN5")
-@RequiredArgsConstructor(onConstructor_ = {@Inject})
+//@Service
+//@Named("isisJdoDn5.IsisPlatformTransactionManagerForJdo")
+//@Order(OrderPrecedence.MIDPOINT)
+//@Primary
+//@Qualifier("JdoDN5")
+//@RequiredArgsConstructor(onConstructor_ = {@Inject})
@Log4j2
-public class IsisPlatformTransactionManagerForJdo extends AbstractPlatformTransactionManager {
+public class IsisPlatformTransactionManagerForJdoNoMore extends AbstractPlatformTransactionManager {
private static final long serialVersionUID = 1L;
- private final InteractionFactory isisInteractionFactory;
- private final EventBusService eventBusService;
- private final InteractionTracker isisInteractionTracker;
+ private InteractionFactory isisInteractionFactory;
+ private EventBusService eventBusService;
+ private InteractionTracker isisInteractionTracker;
@Override
protected Object doGetTransaction() throws TransactionException {
diff --git a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/transaction/TxManagerInternalFactory.java b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/transaction/TxManagerInternalFactory.java
index deefb58..a48e6c4 100644
--- a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/transaction/TxManagerInternalFactory.java
+++ b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/transaction/TxManagerInternalFactory.java
@@ -39,7 +39,7 @@ public class TxManagerInternalFactory {
isisInteractionTracker.currentInteractionSession()
.map(interaction->interaction.putAttribute(_TxProcessor.class, txMan));
- return txMan;
+ return mmc.getTransactionService();
}
diff --git a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/transaction/_TxProcessor.java b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/transaction/_TxProcessor.java
index ebaf294..7624451 100644
--- a/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/transaction/_TxProcessor.java
+++ b/persistence/jdo/integration/src/main/java/org/apache/isis/persistence/jdo/integration/transaction/_TxProcessor.java
@@ -16,19 +16,15 @@
* specific language governing permissions and limitations
* under the License.
*/
-
package org.apache.isis.persistence.jdo.integration.transaction;
-import java.util.concurrent.Callable;
import java.util.function.Supplier;
import javax.enterprise.inject.Vetoed;
import org.apache.isis.applib.services.iactn.Interaction;
import org.apache.isis.applib.services.iactn.InteractionContext;
-import org.apache.isis.applib.services.xactn.TransactionalProcessor;
import org.apache.isis.commons.exceptions.IsisException;
-import org.apache.isis.commons.functional.Result;
import org.apache.isis.commons.internal.exceptions._Exceptions;
import org.apache.isis.core.metamodel.context.MetaModelContext;
import org.apache.isis.core.transaction.integration.IsisTransactionAspectSupport;
@@ -40,9 +36,7 @@ import lombok.val;
import lombok.extern.log4j.Log4j2;
@Vetoed @Log4j2
-class _TxProcessor
-implements
- TransactionalProcessor {
+class _TxProcessor {
// -- constructor, fields
@@ -319,11 +313,6 @@ implements
}
}
- @Override
- public <T> Result<T> executeWithinTransaction(Callable<T> callable) {
- return mmc.getTransactionService().executeWithinTransaction(callable);
- }
-
// -- HELPER
private _Tx getCurrentTransaction() {
diff --git a/persistence/jdo/lightweight/src/main/java/org/apache/isis/persistence/jdo/lightweight/IsisModuleJdoLightweight.java b/persistence/jdo/lightweight/src/main/java/org/apache/isis/persistence/jdo/lightweight/IsisModuleJdoLightweight.java
index 232979f..0d51281 100644
--- a/persistence/jdo/lightweight/src/main/java/org/apache/isis/persistence/jdo/lightweight/IsisModuleJdoLightweight.java
+++ b/persistence/jdo/lightweight/src/main/java/org/apache/isis/persistence/jdo/lightweight/IsisModuleJdoLightweight.java
@@ -18,7 +18,6 @@
*/
package org.apache.isis.persistence.jdo.lightweight;
-import java.util.HashMap;
import java.util.List;
import javax.inject.Named;
@@ -85,7 +84,7 @@ public class IsisModuleJdoLightweight {
val tapmfProxy = new TransactionAwarePersistenceManagerFactoryProxy();
tapmfProxy.setTargetPersistenceManagerFactory(pmf);
- tapmfProxy.setAllowCreate(true);
+ tapmfProxy.setAllowCreate(false);
return tapmfProxy;
}
@@ -93,17 +92,14 @@ public class IsisModuleJdoLightweight {
public LocalPersistenceManagerFactoryBean getLocalPersistenceManagerFactoryBean(
final DnSettings dnSettings) {
- val jdoPropertyMap = new HashMap<String, Object>();
- dnSettings.getAsMap().forEach(jdoPropertyMap::put);
-
val lpmfBean = new LocalPersistenceManagerFactoryBean();
- lpmfBean.setJdoPropertyMap(jdoPropertyMap);
+ lpmfBean.setJdoPropertyMap(dnSettings.getAsProperties());
return lpmfBean;
}
@Bean @Primary
- public JdoTransactionManager getJdoTransactionManager(TransactionAwarePersistenceManagerFactoryProxy tapmfProxy) {
- return new JdoTransactionManager(tapmfProxy.getPersistenceManagerFactory());
+ public JdoTransactionManager getJdoTransactionManager(LocalPersistenceManagerFactoryBean localPmf) {
+ return new JdoTransactionManager(localPmf.getObject());
}
}
diff --git a/persistence/jdo/lightweight/src/main/java/org/apache/isis/persistence/jdo/lightweight/metamodel/facets/entity/JdoEntityFacet.java b/persistence/jdo/lightweight/src/main/java/org/apache/isis/persistence/jdo/lightweight/metamodel/facets/entity/JdoEntityFacet.java
index bb32635..190f018 100644
--- a/persistence/jdo/lightweight/src/main/java/org/apache/isis/persistence/jdo/lightweight/metamodel/facets/entity/JdoEntityFacet.java
+++ b/persistence/jdo/lightweight/src/main/java/org/apache/isis/persistence/jdo/lightweight/metamodel/facets/entity/JdoEntityFacet.java
@@ -28,11 +28,11 @@ import org.apache.isis.applib.query.NamedQuery;
import org.apache.isis.applib.query.Query;
import org.apache.isis.applib.services.repository.EntityState;
import org.apache.isis.commons.collections.Can;
-import org.apache.isis.commons.internal.base._Casts;
-import org.apache.isis.commons.internal.base._Lazy;
+import org.apache.isis.commons.internal.assertions._Assert;
import org.apache.isis.commons.internal.base._NullSafe;
import org.apache.isis.commons.internal.collections._Maps;
import org.apache.isis.commons.internal.exceptions._Exceptions;
+import org.apache.isis.core.metamodel.adapter.oid.Oid;
import org.apache.isis.core.metamodel.context.MetaModelContext;
import org.apache.isis.core.metamodel.facetapi.FacetAbstract;
import org.apache.isis.core.metamodel.facetapi.FacetHolder;
@@ -40,7 +40,7 @@ import org.apache.isis.core.metamodel.facets.object.entity.EntityFacet;
import org.apache.isis.core.metamodel.spec.ManagedObject;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.persistence.jdo.applib.integration.JdoSupportService;
-import org.apache.isis.persistence.jdo.lightweight.metamodel.facets.entity.JdoEntityFacetFactory.JdoObjectIdSerializer;
+import org.apache.isis.persistence.jdo.datanucleus.oid.JdoObjectIdSerializer;
import org.apache.isis.persistence.jdo.provider.entities.JdoFacetContext;
import lombok.NonNull;
@@ -102,7 +102,7 @@ implements EntityFacet {
pojo.getClass().getName());
}
- return getObjectIdSerializer().stringify(primaryKey);
+ return JdoObjectIdSerializer.toOidIdentifier(primaryKey);
}
@@ -111,7 +111,11 @@ implements EntityFacet {
final @NonNull ObjectSpecification entitySpec,
final @NonNull String identifier) {
- val primaryKey = getObjectIdSerializer().parse(identifier);
+ _Assert.assertTrue(entitySpec.isEntity());
+
+ val rootOid = Oid.Factory.root(entitySpec.getSpecId(), identifier);
+
+ val primaryKey = JdoObjectIdSerializer.toJdoObjectId(entitySpec, rootOid);
val persistenceManager = getPersistenceManager();
val entity = persistenceManager.getObjectById(entityClass, primaryKey);
@@ -252,17 +256,6 @@ implements EntityFacet {
// -- OBJECT ID SERIALIZATION
- private final _Lazy<JdoObjectIdSerializer<Object>> objectIdSerializerRef = _Lazy.threadSafe(this::createObjectIdSerializer);
-
- protected JdoObjectIdSerializer<Object> getObjectIdSerializer() {
- return objectIdSerializerRef.get();
- }
-
- protected JdoObjectIdSerializer<Object> createObjectIdSerializer() {
- final Class<?> primaryKeyType = getPersistenceManager().getObjectIdClass(entityClass);
- return _Casts.uncheckedCast(JdoEntityFacetFactory
- .createJdoObjectIdSerializer(primaryKeyType, metaModelContext.getServiceRegistry()));
- }
// -- DEPENDENCIES
diff --git a/persistence/jdo/lightweight/src/main/java/org/apache/isis/persistence/jdo/lightweight/metamodel/facets/entity/JdoEntityFacetFactory.java b/persistence/jdo/lightweight/src/main/java/org/apache/isis/persistence/jdo/lightweight/metamodel/facets/entity/JdoEntityFacetFactory.java
index 4562ad9..18127e5 100644
--- a/persistence/jdo/lightweight/src/main/java/org/apache/isis/persistence/jdo/lightweight/metamodel/facets/entity/JdoEntityFacetFactory.java
+++ b/persistence/jdo/lightweight/src/main/java/org/apache/isis/persistence/jdo/lightweight/metamodel/facets/entity/JdoEntityFacetFactory.java
@@ -21,21 +21,13 @@ package org.apache.isis.persistence.jdo.lightweight.metamodel.facets.entity;
import javax.inject.Inject;
import javax.jdo.annotations.PersistenceCapable;
-import org.apache.isis.applib.services.registry.ServiceRegistry;
-import org.apache.isis.applib.services.urlencoding.UrlEncodingService;
import org.apache.isis.commons.collections.ImmutableEnumSet;
-import org.apache.isis.commons.internal.base._Casts;
-import org.apache.isis.commons.internal.base._Strings;
-import org.apache.isis.commons.internal.memento._Mementos;
-import org.apache.isis.commons.internal.memento._Mementos.SerializingAdapter;
import org.apache.isis.core.metamodel.facetapi.FeatureType;
import org.apache.isis.core.metamodel.facets.Annotations;
import org.apache.isis.core.metamodel.facets.FacetFactoryAbstract;
import org.apache.isis.persistence.jdo.applib.integration.JdoSupportService;
import org.apache.isis.persistence.jdo.provider.entities.JdoFacetContext;
-import lombok.NonNull;
-import lombok.RequiredArgsConstructor;
import lombok.val;
public class JdoEntityFacetFactory extends FacetFactoryAbstract {
@@ -63,108 +55,6 @@ public class JdoEntityFacetFactory extends FacetFactoryAbstract {
addFacet(jdoEntityFacet);
}
-
-
- // -- HELPER - OBJECT ID SERIALIZATION
-
-
- @SuppressWarnings("rawtypes")
- static JdoObjectIdSerializer createJdoObjectIdSerializer(
- final @NonNull Class<?> primaryKeyType,
- final @NonNull ServiceRegistry serviceRegistry) {
-
-
- // not strictly required, but to have simpler entity URLs for simple primary-key types
- {
- if(primaryKeyType.equals(Long.class)
- || primaryKeyType.equals(long.class)) {
- return new LongIdSerializer();
- }
- if(primaryKeyType.equals(Integer.class)
- || primaryKeyType.equals(int.class)) {
- return new IntegerIdSerializer();
- }
- if(primaryKeyType.equals(Short.class)
- || primaryKeyType.equals(short.class)) {
- return new ShortIdSerializer();
- }
- if(primaryKeyType.equals(Byte.class)
- || primaryKeyType.equals(byte.class)) {
- return new ByteIdSerializer();
- }
- }
-
- val codec = serviceRegistry.lookupServiceElseFail(UrlEncodingService.class);
- val serializer = serviceRegistry.lookupServiceElseFail(SerializingAdapter.class);
- return new JdoObjectIdSerializerUsingMementos<>(primaryKeyType, codec, serializer);
- }
-
-
- @RequiredArgsConstructor
- static abstract class JdoObjectIdSerializer<T> {
- @SuppressWarnings("unused")
- final Class<T> primaryKeyType;
- abstract String stringify(T id);
- abstract T parse(String stringifiedPrimaryKey);
- }
-
- private static class LongIdSerializer extends JdoObjectIdSerializer<Long> {
- public LongIdSerializer() { super(Long.class); }
- @Override String stringify(Long id) { return id.toString(); }
- @Override Long parse(String stringifiedPrimaryKey) { return Long.parseLong(stringifiedPrimaryKey); }
- }
- private static class IntegerIdSerializer extends JdoObjectIdSerializer<Integer> {
- public IntegerIdSerializer() { super(Integer.class); }
- @Override String stringify(Integer id) { return id.toString(); }
- @Override Integer parse(String stringifiedPrimaryKey) { return Integer.parseInt(stringifiedPrimaryKey); }
- }
- private static class ShortIdSerializer extends JdoObjectIdSerializer<Short> {
- public ShortIdSerializer() { super(Short.class); }
- @Override String stringify(Short id) { return id.toString(); }
- @Override Short parse(String stringifiedPrimaryKey) { return Short.parseShort(stringifiedPrimaryKey); }
- }
- private static class ByteIdSerializer extends JdoObjectIdSerializer<Byte> {
- public ByteIdSerializer() { super(Byte.class); }
- @Override String stringify(Byte id) { return id.toString(); }
- @Override Byte parse(String stringifiedPrimaryKey) { return Byte.parseByte(stringifiedPrimaryKey); }
- }
-
- private static class JdoObjectIdSerializerUsingMementos<T> extends JdoObjectIdSerializer<T> {
- private final UrlEncodingService codec;
- private final SerializingAdapter serializer;
-
- public JdoObjectIdSerializerUsingMementos(
- final @NonNull Class<T> primaryKeyType,
- final @NonNull UrlEncodingService codec,
- final @NonNull SerializingAdapter serializer) {
- super(primaryKeyType);
- this.codec = codec;
- this.serializer = serializer;
- }
-
- public String stringify(Object id) {
- return newMemento().put("id", id).asString();
- }
-
- public T parse(final String stringifiedPrimaryKey) {
- if(_Strings.isEmpty(stringifiedPrimaryKey)) {
- return null;
- }
- return _Casts.uncheckedCast(parseMemento(stringifiedPrimaryKey).get("id", Object.class));
- }
-
- // -- HELPER
-
- private _Mementos.Memento newMemento(){
- return _Mementos.create(codec, serializer);
- }
-
- private _Mementos.Memento parseMemento(String input){
- return _Mementos.parse(codec, serializer, input);
- }
-
- }
-
}
diff --git a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/applayer/ApplicationLayerTestFactory.java b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/applayer/ApplicationLayerTestFactory.java
index 5216021..37091c0 100644
--- a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/applayer/ApplicationLayerTestFactory.java
+++ b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/applayer/ApplicationLayerTestFactory.java
@@ -190,7 +190,7 @@ public class ApplicationLayerTestFactory {
preCommitListener.setVerifier(verifier);
- transactionService.executeWithinTransaction(()->{
+ transactionService.runWithinCurrentTransactionElseCreateNew(()->{
// when - direct change (circumventing the framework)
book.setName("Book #2");
diff --git a/regressiontests/stable/src/test/java/org/apache/isis/testdomain/persistence/jpa/JpaBootstrappingTest.java b/regressiontests/stable/src/test/java/org/apache/isis/testdomain/persistence/jpa/JpaBootstrappingTest.java
index 5154db3..2595533 100644
--- a/regressiontests/stable/src/test/java/org/apache/isis/testdomain/persistence/jpa/JpaBootstrappingTest.java
+++ b/regressiontests/stable/src/test/java/org/apache/isis/testdomain/persistence/jpa/JpaBootstrappingTest.java
@@ -18,6 +18,11 @@
*/
package org.apache.isis.testdomain.persistence.jpa;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
import java.sql.SQLException;
import java.util.Optional;
import java.util.SortedSet;
@@ -38,11 +43,6 @@ import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
import org.apache.isis.applib.services.repository.RepositoryService;
import org.apache.isis.core.config.presets.IsisPresets;
import org.apache.isis.core.metamodel.facets.object.entity.EntityFacet;
@@ -122,9 +122,13 @@ class JpaBootstrappingTest extends IsisIntegrationTestAbstract {
@Test @Order(0)
void jpaEntities_shouldBeRecognisedAsSuch() {
- val spec = specLoader.loadSpecification(JpaProduct.class);
- assertTrue(spec.isEntity());
- assertNotNull(spec.getFacet(EntityFacet.class));
+ val productSpec = specLoader.loadSpecification(JpaProduct.class);
+ assertTrue(productSpec.isEntity());
+ assertNotNull(productSpec.getFacet(EntityFacet.class));
+
+ val inventorySpec = specLoader.loadSpecification(JpaInventory.class);
+ assertTrue(inventorySpec.isEntity());
+ assertNotNull(inventorySpec.getFacet(EntityFacet.class));
}
@Test @Order(1) @Rollback(false)
diff --git a/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jdo/isis/JdoIsisTransactionRollbackTest_usingTransactionService.java b/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jdo/isis/JdoIsisTransactionRollbackTest_usingTransactionService.java
index 1a2749f..cc60e39 100644
--- a/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jdo/isis/JdoIsisTransactionRollbackTest_usingTransactionService.java
+++ b/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jdo/isis/JdoIsisTransactionRollbackTest_usingTransactionService.java
@@ -64,7 +64,7 @@ class JdoIsisTransactionRollbackTest_usingTransactionService extends IsisIntegra
assertEquals(0, repository.allInstances(JdoBook.class).size());
- transactionService.executeWithinTransaction(()->{
+ transactionService.runWithinCurrentTransactionElseCreateNew(()->{
fixtureScripts.runPersona(JdoTestDomainPersona.InventoryWith1Book);
@@ -81,7 +81,7 @@ class JdoIsisTransactionRollbackTest_usingTransactionService extends IsisIntegra
// expected pre condition
assertEquals(0, repository.allInstances(JdoBook.class).size());
- val result = transactionService.executeWithinTransaction(()->{
+ val result = transactionService.runWithinCurrentTransactionElseCreateNew(()->{
fixtureScripts.runPersona(JdoTestDomainPersona.InventoryWith1Book);
diff --git a/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jdo/isis/JdoIsisTransactionRollbackTest_usingTransactional.java b/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jdo/isis/JdoIsisTransactionRollbackTest_usingTransactional.java
index 7c32036..e055b92 100644
--- a/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jdo/isis/JdoIsisTransactionRollbackTest_usingTransactional.java
+++ b/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jdo/isis/JdoIsisTransactionRollbackTest_usingTransactional.java
@@ -18,6 +18,8 @@
*/
package org.apache.isis.testdomain.transactions.jdo.isis;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
import javax.inject.Inject;
import org.junit.jupiter.api.MethodOrderer;
@@ -26,18 +28,15 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Commit;
-import org.springframework.test.context.TestPropertySource;
import org.springframework.transaction.annotation.Transactional;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
import org.apache.isis.applib.services.repository.RepositoryService;
-import org.apache.isis.core.config.presets.IsisPresets;
+import org.apache.isis.commons.internal.debug._Probe;
+import org.apache.isis.core.interaction.session.InteractionFactory;
import org.apache.isis.testdomain.conf.Configuration_usingJdoIsis;
import org.apache.isis.testdomain.jdo.JdoTestDomainPersona;
import org.apache.isis.testdomain.jdo.entities.JdoBook;
import org.apache.isis.testing.fixtures.applib.fixturescripts.FixtureScripts;
-import org.apache.isis.testing.integtestsupport.applib.IsisIntegrationTestAbstract;
/**
* These tests use the {@code @Transactional} annotation as provided by Spring.
@@ -46,40 +45,69 @@ import org.apache.isis.testing.integtestsupport.applib.IsisIntegrationTestAbstra
*/
@SpringBootTest(
classes = {
- Configuration_usingJdoIsis.class,
+ Configuration_usingJdoIsis.class
+ },
+ properties = {
+ "logging.level.org.apache.isis.persistence.jdo.*=DEBUG",
+ "logging.level.org.springframework.test.context.transaction.*=DEBUG",
+ "logging.level.org.datanucleus.*=DEBUG",
+ "logging.config=log4j2-debug-persistence.xml"
+
})
@Transactional
-@TestPropertySource(IsisPresets.UseLog4j2Test)
+//@TestPropertySource(IsisPresets.UseLog4j2Test)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
-class JdoIsisTransactionRollbackTest_usingTransactional extends IsisIntegrationTestAbstract {
+class JdoIsisTransactionRollbackTest_usingTransactional
+// extends IsisIntegrationTestAbstract
+{
@Inject private FixtureScripts fixtureScripts;
@Inject private RepositoryService repository;
+ @Inject private InteractionFactory interactionFactory;
@Test @Order(1) @Commit
void cleanup_justInCase() {
+
// cleanup just in case
fixtureScripts.runPersona(JdoTestDomainPersona.PurgeAll);
}
@Test @Order(2)
void happyCaseTx_shouldCommit() {
+
+ _Probe.errOut("before interaction");
- // expected pre condition
- assertEquals(0, repository.allInstances(JdoBook.class).size());
+ interactionFactory.runAnonymous(()->{
+
+ // expected pre condition
+ assertEquals(0, repository.allInstances(JdoBook.class).size());
+
+ _Probe.errOut("before fixture");
+
+ fixtureScripts.runPersona(JdoTestDomainPersona.InventoryWith1Book);
+
+ _Probe.errOut("after fixture");
- fixtureScripts.runPersona(JdoTestDomainPersona.InventoryWith1Book);
+ // expected post condition
+ //assertEquals(1, repository.allInstances(JdoBook.class).size());
+
+
+ });
- // expected post condition
- assertEquals(1, repository.allInstances(JdoBook.class).size());
+ _Probe.errOut("after interaction");
}
@Test @Order(3)
void previousTest_shouldHaveBeenRolledBack() {
-
+
+ interactionFactory.runAnonymous(()->{
+
// expected condition
assertEquals(0, repository.allInstances(JdoBook.class).size());
+
+ });
+
}
}
diff --git a/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jdo/isis/JdoIsisTransactionScopeListenerTest.java b/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jdo/isis/JdoIsisTransactionScopeListenerTest.java
index 7607dc5..f4568aa 100644
--- a/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jdo/isis/JdoIsisTransactionScopeListenerTest.java
+++ b/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jdo/isis/JdoIsisTransactionScopeListenerTest.java
@@ -88,7 +88,7 @@ class JdoIsisTransactionScopeListenerTest {
assertEquals(0, repository.allInstances(JdoBook.class).size());
// new transaction (#3)
- transactionService.executeWithinTransaction(()->{
+ transactionService.runWithinCurrentTransactionElseCreateNew(()->{
fixtureScripts.runPersona(JdoTestDomainPersona.InventoryWith1Book);
diff --git a/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jdo/spring/JdoSpringTransactionRollbackTest_usingTransactionService.java b/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jdo/spring/JdoSpringTransactionRollbackTest_usingTransactionService.java
index 45b9606..05ae949 100644
--- a/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jdo/spring/JdoSpringTransactionRollbackTest_usingTransactionService.java
+++ b/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jdo/spring/JdoSpringTransactionRollbackTest_usingTransactionService.java
@@ -18,17 +18,16 @@
*/
package org.apache.isis.testdomain.transactions.jdo.spring;
+import static org.junit.Assert.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
import javax.inject.Inject;
import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
import org.apache.isis.applib.services.repository.RepositoryService;
import org.apache.isis.applib.services.xactn.TransactionService;
import org.apache.isis.commons.internal.exceptions._Exceptions;
@@ -39,6 +38,8 @@ import org.apache.isis.testdomain.jdo.entities.JdoBook;
import org.apache.isis.testing.fixtures.applib.fixturescripts.FixtureScripts;
import org.apache.isis.testing.integtestsupport.applib.IsisIntegrationTestAbstract;
+import lombok.val;
+
@SpringBootTest(
classes = {
Configuration_usingJdoSpring.class,
@@ -56,44 +57,48 @@ class JdoSpringTransactionRollbackTest_usingTransactionService extends IsisInteg
fixtureScripts.runPersona(JdoTestDomainPersona.PurgeAll);
}
- @Test @Disabled("wip")
+ @Test
void happyCaseTx_shouldCommit() {
- // expected pre condition
- assertEquals(0, repository.allInstances(JdoBook.class).size());
-
-
- transactionService.executeWithinTransaction(()->{
+ transactionService.runWithinCurrentTransactionElseCreateNew(()->{
+
+ // expected pre condition
+ assertEquals(0, repository.allInstances(JdoBook.class).size());
fixtureScripts.runPersona(JdoTestDomainPersona.InventoryWith1Book);
+ // expected post condition
+ assertEquals(1, repository.allInstances(JdoBook.class).size());
+
});
-
- // expected post condition
- assertEquals(1, repository.allInstances(JdoBook.class).size());
}
- @Test @Disabled("wip")
+ @Test
void whenExceptionWithinTx_shouldRollback() {
- // expected pre condition
- assertEquals(0, repository.allInstances(JdoBook.class).size());
-
- assertThrows(RuntimeException.class, ()->{
+ transactionService.runWithinCurrentTransactionElseCreateNew(()->{
- transactionService.executeWithinTransaction(()->{
+ // expected pre condition
+ assertEquals(0, repository.allInstances(JdoBook.class).size());
+ });
- fixtureScripts.runPersona(JdoTestDomainPersona.InventoryWith1Book);
+ val result = transactionService.runWithinCurrentTransactionElseCreateNew(()->{
+
+ fixtureScripts.runPersona(JdoTestDomainPersona.InventoryWith1Book);
- throw _Exceptions.unrecoverable("Test: force current tx to rollback");
-
- });
+ throw _Exceptions.unrecoverable("Test: force current tx to rollback");
});
- // expected post condition
- assertEquals(0, repository.allInstances(JdoBook.class).size());
+ assertTrue(result.isFailure());
+
+ transactionService.runWithinCurrentTransactionElseCreateNew(()->{
+
+ // expected post condition
+ assertEquals(0, repository.allInstances(JdoBook.class).size());
+
+ });
}
diff --git a/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jdo/spring/JdoSpringTransactionRollbackTest_usingTransactional.java b/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jdo/spring/JdoSpringTransactionRollbackTest_usingTransactional.java
index 4b85d56..6b96f13 100644
--- a/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jdo/spring/JdoSpringTransactionRollbackTest_usingTransactional.java
+++ b/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jdo/spring/JdoSpringTransactionRollbackTest_usingTransactional.java
@@ -18,9 +18,12 @@
*/
package org.apache.isis.testdomain.transactions.jdo.spring;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.HashSet;
+
import javax.inject.Inject;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
@@ -30,15 +33,14 @@ import org.springframework.test.annotation.Commit;
import org.springframework.test.context.TestPropertySource;
import org.springframework.transaction.annotation.Transactional;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
import org.apache.isis.applib.services.repository.RepositoryService;
import org.apache.isis.core.config.presets.IsisPresets;
import org.apache.isis.testdomain.conf.Configuration_usingJdoSpring;
-import org.apache.isis.testdomain.jdo.JdoTestDomainPersona;
import org.apache.isis.testdomain.jdo.entities.JdoBook;
-import org.apache.isis.testing.fixtures.applib.fixturescripts.FixtureScripts;
-import org.apache.isis.testing.integtestsupport.applib.IsisIntegrationTestAbstract;
+import org.apache.isis.testdomain.jdo.entities.JdoInventory;
+import org.apache.isis.testdomain.jdo.entities.JdoProduct;
+
+import lombok.val;
/**
* These tests use the {@code @Transactional} annotation as provided by Spring.
@@ -48,37 +50,59 @@ import org.apache.isis.testing.integtestsupport.applib.IsisIntegrationTestAbstra
@SpringBootTest(
classes = {
Configuration_usingJdoSpring.class,
+ },
+ properties = {
+ "logging.level.org.apache.isis.persistence.jdo.*=DEBUG",
+ "logging.level.org.springframework.test.context.transaction.*=DEBUG"
})
@Transactional
@TestPropertySource(IsisPresets.UseLog4j2Test)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
-class JdoSpringTransactionRollbackTest_usingTransactional extends IsisIntegrationTestAbstract {
-
- @Inject private FixtureScripts fixtureScripts;
+class JdoSpringTransactionRollbackTest_usingTransactional
+//extends IsisIntegrationTestAbstract
+{
+
@Inject private RepositoryService repository;
-
+
@Test @Order(1) @Commit
void cleanup_justInCase() {
// cleanup just in case
- fixtureScripts.runPersona(JdoTestDomainPersona.PurgeAll);
+ repository.removeAll(JdoProduct.class);
+ repository.removeAll(JdoInventory.class);
}
-
+
@Test @Order(2)
void happyCaseTx_shouldCommit() {
-
+
+ System.err.println("== ENTER TEST");
+
// expected pre condition
assertEquals(0, repository.allInstances(JdoBook.class).size());
-
- fixtureScripts.runPersona(JdoTestDomainPersona.InventoryWith1Book);
-
+
+ val products = new HashSet<JdoProduct>();
+
+ products.add(JdoBook.of(
+ "Sample Book", "A sample book for testing.", 99.,
+ "Sample Author", "Sample ISBN", "Sample Publisher"));
+
+ val inventory = JdoInventory.of("Sample Inventory", products);
+
+ System.err.println("== ENTER PERSIST");
+
+ repository.persist(inventory);
+
+ System.err.println("== EXIT PERSIST");
+
// expected post condition
assertEquals(1, repository.allInstances(JdoBook.class).size());
-
+
+ System.err.println("== EXIT TEST");
+
}
-
- @Test @Order(3) @Disabled("wip")
+
+ @Test @Order(3)
void previousTest_shouldHaveBeenRolledBack() {
-
+
// expected condition
assertEquals(0, repository.allInstances(JdoBook.class).size());
}
diff --git a/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jdo/spring/JdoSpringTransactionScopeListenerTest.java b/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jdo/spring/JdoSpringTransactionScopeListenerTest.java
index ee2ff49..8a0dc9a 100644
--- a/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jdo/spring/JdoSpringTransactionScopeListenerTest.java
+++ b/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jdo/spring/JdoSpringTransactionScopeListenerTest.java
@@ -89,7 +89,7 @@ class JdoSpringTransactionScopeListenerTest {
assertEquals(0, repository.allInstances(JdoBook.class).size());
// new transaction (#3)
- transactionService.executeWithinTransaction(()->{
+ transactionService.runWithinCurrentTransactionElseCreateNew(()->{
fixtureScripts.runPersona(JdoTestDomainPersona.InventoryWith1Book);
diff --git a/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jpa/JpaTransactionRollbackTest_usingTransactionService.java b/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jpa/JpaTransactionRollbackTest_usingTransactionService.java
index 31eda05..740672d 100644
--- a/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jpa/JpaTransactionRollbackTest_usingTransactionService.java
+++ b/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jpa/JpaTransactionRollbackTest_usingTransactionService.java
@@ -18,83 +18,95 @@
*/
package org.apache.isis.testdomain.transactions.jpa;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
import javax.inject.Inject;
import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
import org.apache.isis.applib.services.repository.RepositoryService;
import org.apache.isis.applib.services.xactn.TransactionService;
-import org.apache.isis.commons.internal.exceptions._Exceptions;
import org.apache.isis.core.config.presets.IsisPresets;
import org.apache.isis.testdomain.conf.Configuration_usingJpa;
-import org.apache.isis.testdomain.jdo.JdoTestDomainPersona;
import org.apache.isis.testdomain.jpa.JpaTestDomainPersona;
import org.apache.isis.testdomain.jpa.entities.JpaBook;
import org.apache.isis.testing.fixtures.applib.fixturescripts.FixtureScripts;
-import org.apache.isis.testing.integtestsupport.applib.IsisIntegrationTestAbstract;
+
+import lombok.val;
@SpringBootTest(
classes = {
Configuration_usingJpa.class,
+ },
+ properties = {
+ "logging.level.org.apache.isis.persistence.jdo.spring.*=DEBUG",
+ "logging.level.org.springframework.test.context.transaction.*=DEBUG"
})
@TestPropertySource(IsisPresets.UseLog4j2Test)
-class JpaTransactionRollbackTest_usingTransactionService extends IsisIntegrationTestAbstract {
+class JpaTransactionRollbackTest_usingTransactionService
+//extends IsisIntegrationTestAbstract
+{
@Inject private FixtureScripts fixtureScripts;
@Inject private TransactionService transactionService;
@Inject private RepositoryService repository;
-
+
@BeforeEach
void setUp() {
+
// cleanup
- fixtureScripts.runPersona(JdoTestDomainPersona.PurgeAll);
+ fixtureScripts.runPersona(JpaTestDomainPersona.PurgeAll);
}
- @Test @Disabled("wip")
+ @Test
void happyCaseTx_shouldCommit() {
- // expected pre condition
- assertEquals(0, repository.allInstances(JpaBook.class).size());
+ transactionService.runWithinCurrentTransactionElseCreateNew(()->{
+ // expected pre condition
+ assertEquals(0, repository.allInstances(JpaBook.class).size());
+ });
- transactionService.executeWithinTransaction(()->{
+ transactionService.runWithinCurrentTransactionElseCreateNew(()->{
fixtureScripts.runPersona(JpaTestDomainPersona.InventoryWith1Book);
-
});
- // expected post condition
- assertEquals(1, repository.allInstances(JpaBook.class).size());
+ transactionService.runWithinCurrentTransactionElseCreateNew(()->{
+
+ // expected post condition
+ assertEquals(1, repository.allInstances(JpaBook.class).size());
+ });
}
- @Test @Disabled("wip")
+ @Test
void whenExceptionWithinTx_shouldRollback() {
- // expected pre condition
- assertEquals(0, repository.allInstances(JpaBook.class).size());
-
- assertThrows(RuntimeException.class, ()->{
-
- transactionService.executeWithinTransaction(()->{
-
- fixtureScripts.runPersona(JpaTestDomainPersona.InventoryWith1Book);
-
- throw _Exceptions.unrecoverable("Test: force current tx to rollback");
-
- });
-
+ transactionService.runWithinCurrentTransactionElseCreateNew(()->{
+
+ // expected pre condition
+ assertEquals(0, repository.allInstances(JpaBook.class).size());
});
- // expected post condition
- assertEquals(0, repository.allInstances(JpaBook.class).size());
+ val result = transactionService.runWithinCurrentTransactionElseCreateNew(()->{
+
+ fixtureScripts.runPersona(JpaTestDomainPersona.InventoryWith1Book);
+
+ throw new RuntimeException("Test: force current tx to rollback");
+ });
+
+ assertTrue(result.isFailure());
+
+ transactionService.runWithinCurrentTransactionElseCreateNew(()->{
+
+ // expected post condition
+ assertEquals(0, repository.allInstances(JpaBook.class).size());
+ });
}
diff --git a/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jpa/JpaTransactionRollbackTest_usingTransactional.java b/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jpa/JpaTransactionRollbackTest_usingTransactional.java
index 513d66c..8a68009 100644
--- a/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jpa/JpaTransactionRollbackTest_usingTransactional.java
+++ b/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jpa/JpaTransactionRollbackTest_usingTransactional.java
@@ -18,6 +18,8 @@
*/
package org.apache.isis.testdomain.transactions.jpa;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
import javax.inject.Inject;
import org.junit.jupiter.api.MethodOrderer;
@@ -29,15 +31,13 @@ import org.springframework.test.annotation.Commit;
import org.springframework.test.context.TestPropertySource;
import org.springframework.transaction.annotation.Transactional;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
import org.apache.isis.applib.services.repository.RepositoryService;
+import org.apache.isis.commons.internal.debug._Probe;
import org.apache.isis.core.config.presets.IsisPresets;
import org.apache.isis.testdomain.conf.Configuration_usingJpa;
import org.apache.isis.testdomain.jpa.JpaTestDomainPersona;
import org.apache.isis.testdomain.jpa.entities.JpaBook;
import org.apache.isis.testing.fixtures.applib.fixturescripts.FixtureScripts;
-import org.apache.isis.testing.integtestsupport.applib.IsisIntegrationTestAbstract;
/**
* These tests use the {@code @Transactional} annotation as provided by Spring.
@@ -47,11 +47,18 @@ import org.apache.isis.testing.integtestsupport.applib.IsisIntegrationTestAbstra
@SpringBootTest(
classes = {
Configuration_usingJpa.class,
- })
+ },
+ properties = {
+ "logging.level.org.apache.isis.core.runtimeservices.session.InteractionFactoryDefault=DEBUG",
+ "logging.level.org.apache.isis.persistence.*=DEBUG",
+ "logging.level.org.springframework.test.context.transaction.*=DEBUG"
+ })
@Transactional
@TestPropertySource(IsisPresets.UseLog4j2Test)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
-class JpaTransactionRollbackTest_usingTransactional extends IsisIntegrationTestAbstract {
+class JpaTransactionRollbackTest_usingTransactional
+//extends IsisIntegrationTestAbstract
+{
@Inject private FixtureScripts fixtureScripts;
@Inject private RepositoryService repository;
@@ -67,15 +74,19 @@ class JpaTransactionRollbackTest_usingTransactional extends IsisIntegrationTestA
// expected pre condition
assertEquals(0, repository.allInstances(JpaBook.class).size());
+
+ _Probe.errOut("before fixture");
fixtureScripts.runPersona(JpaTestDomainPersona.InventoryWith1Book);
+ _Probe.errOut("after fixture");
+
// expected post condition
assertEquals(1, repository.allInstances(JpaBook.class).size());
}
- @Test @Order(3) //@Disabled("wip")
+ @Test @Order(3)
void previousTest_shouldHaveBeenRolledBack() {
// expected condition
diff --git a/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jpa/JpaTransactionScopeListenerTest.java b/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jpa/JpaTransactionScopeListenerTest.java
index 1df816d..e37024d 100644
--- a/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jpa/JpaTransactionScopeListenerTest.java
+++ b/regressiontests/stable/src/test/java/org/apache/isis/testdomain/transactions/jpa/JpaTransactionScopeListenerTest.java
@@ -90,7 +90,7 @@ class JpaTransactionScopeListenerTest {
assertEquals(0, repository.allInstances(JpaBook.class).size());
// new transaction (#3)
- transactionService.executeWithinTransaction(()->{
+ transactionService.runWithinCurrentTransactionElseCreateNew(()->{
fixtureScripts.runPersona(JpaTestDomainPersona.InventoryWith1Book);
diff --git a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/FixtureScripts.java b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/FixtureScripts.java
index 967c81b..dbb3d2b 100644
--- a/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/FixtureScripts.java
+++ b/testing/fixtures/applib/src/main/java/org/apache/isis/testing/fixtures/applib/fixturescripts/FixtureScripts.java
@@ -351,7 +351,7 @@ public class FixtureScripts {
String parameters = null;
isisInteractionFactory.runAnonymous(()->{
- transactionService.executeWithinTransaction(()->{
+ transactionService.runWithinCurrentTransactionElseCreateNew(()->{
runScript(singleScript, parameters);
});
});
@@ -386,7 +386,7 @@ public class FixtureScripts {
public <T> T runBuilder(final BuilderScriptAbstract<T> builderScript) {
return isisInteractionFactory.callAnonymous(()->
- transactionService.executeWithinTransaction(()->
+ transactionService.callWithinCurrentTransactionElseCreateNew(()->
runBuilderScriptNonTransactional(builderScript)
)
)
diff --git a/testing/integtestsupport/applib/src/main/java/org/apache/isis/testing/integtestsupport/applib/IsisInteractionHandler.java b/testing/integtestsupport/applib/src/main/java/org/apache/isis/testing/integtestsupport/applib/IsisInteractionHandler.java
index 342a475..4066828 100644
--- a/testing/integtestsupport/applib/src/main/java/org/apache/isis/testing/integtestsupport/applib/IsisInteractionHandler.java
+++ b/testing/integtestsupport/applib/src/main/java/org/apache/isis/testing/integtestsupport/applib/IsisInteractionHandler.java
@@ -24,20 +24,31 @@ import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
+import org.apache.isis.commons.internal.debug._Probe;
import org.apache.isis.core.interaction.session.InteractionFactory;
public class IsisInteractionHandler implements BeforeEachCallback, AfterEachCallback {
@Override
public void beforeEach(ExtensionContext extensionContext) throws Exception {
+
+ _Probe.errOut("before interaction in");
+
isisInteractionFactory(extensionContext)
.ifPresent(isisInteractionFactory->isisInteractionFactory.openInteraction());
+
+ _Probe.errOut("before interaction out");
}
@Override
public void afterEach(ExtensionContext extensionContext) throws Exception {
+
+ _Probe.errOut("after interaction in");
+
isisInteractionFactory(extensionContext)
.ifPresent(InteractionFactory::closeSessionStack);
+
+ _Probe.errOut("after interaction out");
}
// -- HELPER
diff --git a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/webmodule/IsisRestfulObjectsInteractionFilter.java b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/webmodule/IsisRestfulObjectsInteractionFilter.java
index c3a7006..9ff6973 100644
--- a/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/webmodule/IsisRestfulObjectsInteractionFilter.java
+++ b/viewers/restfulobjects/viewer/src/main/java/org/apache/isis/viewer/restfulobjects/viewer/webmodule/IsisRestfulObjectsInteractionFilter.java
@@ -19,6 +19,8 @@
package org.apache.isis.viewer.restfulobjects.viewer.webmodule;
+import static org.apache.isis.commons.internal.base._With.requires;
+
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
@@ -53,8 +55,6 @@ import org.apache.isis.core.webapp.modules.templresources.TemplateResourceCachin
import org.apache.isis.viewer.restfulobjects.viewer.webmodule.auth.AuthenticationStrategy;
import org.apache.isis.viewer.restfulobjects.viewer.webmodule.auth.AuthenticationStrategyDefault;
-import static org.apache.isis.commons.internal.base._With.requires;
-
import lombok.val;
/**
@@ -382,13 +382,10 @@ public class IsisRestfulObjectsInteractionFilter implements Filter {
authentication,
()->{
- transactionService.executeWithinTransaction(()->{
- try {
- chain.doFilter(request, response);
- } catch (IOException | ServletException e) {
- throw new TransactionalException("", e);
- }
- });
+ transactionService.runWithinCurrentTransactionElseCreateNew(()->
+ chain.doFilter(request, response))
+ .mapFailure(e->new TransactionalException("", e))
+ .nullableOrElseFail();
});
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/accmngt/register/RegisterPanel.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/accmngt/register/RegisterPanel.java
index b153e60..21d8112 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/accmngt/register/RegisterPanel.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/pages/accmngt/register/RegisterPanel.java
@@ -142,7 +142,7 @@ public abstract class RegisterPanel extends PanelBase<UserDetails> {
final UserDetails userDetails = getModelObject();
isisInteractionFactory.runAnonymous(() -> {
- transactionService.executeWithinTransaction(() -> {
+ transactionService.runWithinCurrentTransactionElseCreateNew(() -> {
userRegistrationService.registerUser(userDetails);
removeAccountConfirmation();
});