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

danhaywood pushed a commit to branch CAUSEWAY-4042
in repository https://gitbox.apache.org/repos/asf/causeway.git


The following commit(s) were added to refs/heads/CAUSEWAY-4042 by this push:
     new 4ec463819a0 CAUSEWAY-4042: clear cache in new xactn, preserve message 
if possible
4ec463819a0 is described below

commit 4ec463819a0807ff7bfe3449a3d9388621f986c0
Author: Dan Haywood <[email protected]>
AuthorDate: Mon Jun 29 15:24:42 2026 +0100

    CAUSEWAY-4042: clear cache in new xactn, preserve message if possible
---
 .../applib/exceptions/recoverable/InteractionException.java      | 6 +++++-
 .../causeway/applib/services/wrapper/DisabledException.java      | 6 +++++-
 .../apache/causeway/applib/services/wrapper/HiddenException.java | 4 ++++
 .../causeway/applib/services/wrapper/InvalidException.java       | 4 ++++
 .../runtimeservices/command/CommandExecutorServiceDefault.java   | 9 ++++++---
 .../commandlog/applib/dom/replay/ReplayableCommand.java          | 4 ++++
 6 files changed, 28 insertions(+), 5 deletions(-)

diff --git 
a/api/applib/src/main/java/org/apache/causeway/applib/exceptions/recoverable/InteractionException.java
 
b/api/applib/src/main/java/org/apache/causeway/applib/exceptions/recoverable/InteractionException.java
index dd639e2060f..2d14a2e062e 100644
--- 
a/api/applib/src/main/java/org/apache/causeway/applib/exceptions/recoverable/InteractionException.java
+++ 
b/api/applib/src/main/java/org/apache/causeway/applib/exceptions/recoverable/InteractionException.java
@@ -29,7 +29,11 @@ public abstract class InteractionException extends 
RecoverableException {
     private final InteractionEvent interactionEvent;
 
     public InteractionException(final InteractionEvent interactionEvent) {
-        super(interactionEvent.getReason());
+        this(interactionEvent.getReason(), interactionEvent);
+    }
+
+    public InteractionException(final String message, final InteractionEvent 
interactionEvent) {
+        super(message != null ? message : interactionEvent.getReason());
         this.interactionEvent = interactionEvent;
     }
 
diff --git 
a/api/applib/src/main/java/org/apache/causeway/applib/services/wrapper/DisabledException.java
 
b/api/applib/src/main/java/org/apache/causeway/applib/services/wrapper/DisabledException.java
index 18fac2e8696..9b78def27dd 100644
--- 
a/api/applib/src/main/java/org/apache/causeway/applib/services/wrapper/DisabledException.java
+++ 
b/api/applib/src/main/java/org/apache/causeway/applib/services/wrapper/DisabledException.java
@@ -26,7 +26,7 @@
 /**
  * Superclass of exceptions which indicate an attempt to interact with a class
  * member that is disabled.
- * 
+ *
  * @since 1.x {@index}
  */
 public class DisabledException extends InteractionException {
@@ -37,6 +37,10 @@ public DisabledException(final InteractionEvent 
interactionEvent) {
         super(interactionEvent);
     }
 
+    public DisabledException(final String message, final InteractionEvent 
interactionEvent) {
+        super(message, interactionEvent);
+    }
+
     @Override
     public UsabilityEvent getInteractionEvent() {
         return (UsabilityEvent) super.getInteractionEvent();
diff --git 
a/api/applib/src/main/java/org/apache/causeway/applib/services/wrapper/HiddenException.java
 
b/api/applib/src/main/java/org/apache/causeway/applib/services/wrapper/HiddenException.java
index 27ca08d6a26..38a8b0fee2f 100644
--- 
a/api/applib/src/main/java/org/apache/causeway/applib/services/wrapper/HiddenException.java
+++ 
b/api/applib/src/main/java/org/apache/causeway/applib/services/wrapper/HiddenException.java
@@ -36,6 +36,10 @@ public HiddenException(final InteractionEvent 
interactionEvent) {
         super(interactionEvent);
     }
 
+    public HiddenException(final String message, final InteractionEvent 
interactionEvent) {
+        super(message, interactionEvent);
+    }
+
     @Override
     public VisibilityEvent getInteractionEvent() {
         return (VisibilityEvent) super.getInteractionEvent();
diff --git 
a/api/applib/src/main/java/org/apache/causeway/applib/services/wrapper/InvalidException.java
 
b/api/applib/src/main/java/org/apache/causeway/applib/services/wrapper/InvalidException.java
index e42ecd42cda..0dbb6c5a684 100644
--- 
a/api/applib/src/main/java/org/apache/causeway/applib/services/wrapper/InvalidException.java
+++ 
b/api/applib/src/main/java/org/apache/causeway/applib/services/wrapper/InvalidException.java
@@ -36,6 +36,10 @@ public InvalidException(final InteractionEvent 
interactionEvent) {
         super(interactionEvent);
     }
 
+    public InvalidException(final String message, final InteractionEvent 
interactionEvent) {
+        super(message, interactionEvent);
+    }
+
     @Override
     public ValidityEvent getInteractionEvent() {
         return (ValidityEvent) super.getInteractionEvent();
diff --git 
a/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/command/CommandExecutorServiceDefault.java
 
b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/command/CommandExecutorServiceDefault.java
index aac286f81c0..b3612f3d30c 100644
--- 
a/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/command/CommandExecutorServiceDefault.java
+++ 
b/core/runtimeservices/src/main/java/org/apache/causeway/core/runtimeservices/command/CommandExecutorServiceDefault.java
@@ -233,17 +233,20 @@ private Bookmark doExecuteCommand(final CommandDto dto) {
                 case CHECK:
                     final var visibility = 
objectAction.isVisible(targetAdapter, interactionInitiatedBy, Where.ANYWHERE);
                     if(visibility.isVetoed()) {
-                        throw new HiddenException(new 
ActionVisibilityEvent(targetAdapter.getPojo(), 
objectAction.getFeatureIdentifier()));
+                        final var interactionEvent = new 
ActionVisibilityEvent(targetAdapter.getPojo(), 
objectAction.getFeatureIdentifier());
+                        throw new 
HiddenException(visibility.getReasonAsString().orElse(null), interactionEvent);
                     }
                     final var usability = objectAction.isUsable(targetAdapter, 
interactionInitiatedBy, Where.ANYWHERE);
                     if(usability.isVetoed()) {
-                        throw new DisabledException(new 
ActionUsabilityEvent(targetAdapter.getPojo(), 
objectAction.getFeatureIdentifier()));
+                        final var interactionEvent = new 
ActionUsabilityEvent(targetAdapter.getPojo(), 
objectAction.getFeatureIdentifier());
+                        throw new 
DisabledException(usability.getReasonAsString().orElse(null), interactionEvent);
                     }
                     // this checks each arg individually, then all of them as 
a set.
                     final var argumentsValidity = 
objectAction.isArgumentSetValid(interactionHead, argAdapters, 
interactionInitiatedBy);
                     if(argumentsValidity.isVetoed()) {
                         // ActionInvocationEvent is somewhat odd as the 
underlying event, but it is what WrapperFactory does...
-                        throw new InvalidException(new 
ActionInvocationEvent(targetAdapter.getPojo(), 
objectAction.getFeatureIdentifier(), 
argAdapters.stream().map(ManagedObject::getPojo).toArray()));
+                        final var interactionEvent = new 
ActionInvocationEvent(targetAdapter.getPojo(), 
objectAction.getFeatureIdentifier(), 
argAdapters.stream().map(ManagedObject::getPojo).toArray());
+                        throw new 
InvalidException(argumentsValidity.getReasonAsString().orElse(null), 
interactionEvent);
                     }
                     break;
                 case CHECK_BUT_IGNORE:
diff --git 
a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommand.java
 
b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommand.java
index 2529e962ea0..09d9be9a88c 100644
--- 
a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommand.java
+++ 
b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommand.java
@@ -48,6 +48,7 @@
 import org.apache.causeway.applib.services.bookmark.Bookmark;
 import 
org.apache.causeway.applib.services.command.CommandExecutorService.InteractionContextPolicy;
 import org.apache.causeway.applib.services.command.CommandRecordingSuppressed;
+import 
org.apache.causeway.applib.services.queryresultscache.QueryResultsCacheControl;
 import org.apache.causeway.applib.services.wrapper.DisabledException;
 import org.apache.causeway.applib.services.wrapper.HiddenException;
 import org.apache.causeway.applib.services.wrapper.InvalidException;
@@ -625,7 +626,9 @@ CommandDto commandDtoPossiblyRemappedForReplay(final 
CommandLogEntry commandLogE
     }
 
     private Try<Bookmark> tryReplay(final CommandDto commandDto) {
+        final var queryResultsCache = replayContext.queryResultsCache();
         var tryResultBookmark = 
replayContext.transactionService().callTransactional(Propagation.REQUIRES_NEW, 
() -> {
+                    queryResultsCache.onTransactionEnded(); // clear the cache
                     final Bookmark actualResult = 
replayContext.commandExecutorService()
                             // calls transactionService which uses its own try 
to potentially mark _this_ transaction for rollback.
                             
.executeCommand(InteractionContextPolicy.SWITCH_USER_AND_TIME, commandDto)
@@ -637,6 +640,7 @@ private Try<Bookmark> tryReplay(final CommandDto 
commandDto) {
                 .mapFailureToSuccess(ex -> {
                     // use a new transaction to record the failure.
                     
replayContext.transactionService().runTransactional(Propagation.REQUIRES_NEW, 
() -> {
+                        queryResultsCache.onTransactionEnded(); // clear the 
cache
                         onReplayError(ex);
                     });
                     return null;

Reply via email to