You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@causeway.apache.org by da...@apache.org on 2026/06/04 22:46:40 UTC

(causeway) 21/42: CAUSEWAY-4010: ensures that the CommandLogEntry's result ...

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

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

commit 23751efd5e3cd4651068dd26e1eda847efd467de
Author: Dan Haywood <da...@haywood-associates.co.uk>
AuthorDate: Thu Jun 4 16:41:29 2026 +0100

    CAUSEWAY-4010: ensures that the CommandLogEntry's result ...
    
    ... isn't overwritten during init or sync.  Also minor refactoring
---
 .../extensions/commandlog/applib/dom/CommandLogEntry.java     | 11 ++++++++---
 .../commandlog/applib/dom/replay/ReplayableCommand.java       |  5 +++--
 .../applib/dom/replay/ReplayableCommandMappingTest.java       | 10 +++++-----
 3 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/CommandLogEntry.java b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/CommandLogEntry.java
index f217f514b3f..39b4778ac0a 100644
--- a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/CommandLogEntry.java
+++ b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/CommandLogEntry.java
@@ -174,8 +174,12 @@ public void sync(final Command command) {
         setStartedAt(command.getStartedAt());
         setCompletedAt(command.getCompletedAt());
 
-        setResult(command.getResult());
-        setException(command.getException());
+        if (getReplayState().isPendingOrFailed()) {
+            // we DON'T overwrite the result if we're replaying.
+        } else {
+            setResult(command.getResult());
+            setException(command.getException());
+        }
     }
 
 
@@ -209,7 +213,8 @@ protected void init(
                 setCompletedAt(JavaSqlXMLGregorianCalendarMarshalling.toTimestamp(timings.getCompletedAt()));
             });
 
-        copyOver(commandDto, UserDataKeys.RESULT, value -> this.setResult(Bookmark.parse(value).orElse(null)));
+
+        copyOver(commandDto, UserDataKeys.RESULT, value -> Bookmark.parse(value).ifPresent(this::setResult));
         copyOver(commandDto, UserDataKeys.EXCEPTION, this::setException);
 
         setReplayState(replayState);
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 d5fbd16481c..5bd2dc772d6 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
@@ -369,7 +369,8 @@ Try<ReplayableCommand> tryReplayOrRetry() {
             return Try.success(null); // guard against disallowed invocation
         return commandLogEntry()
             .filter(ReplayableCommand::canReplayOrRetryOrMarkForExclusion)
-            .map(commandLogEntry->tryReplay(commandDtoForReplay(commandLogEntry))
+                .map(this::commandDtoPossiblyRemappedForReplay)
+            .map(commandDto->tryReplay(commandDto)
                 .mapSuccessAsNullable(__ -> this))
             // if nothing to do, return with an 'empty success'
             .orElseGet(()->Try.success(null));
@@ -390,7 +391,7 @@ String disableReplayOrRetry() {
      * Replays given command in its own transaction and handles {@link ReplayState} transition to
      * either {@link ReplayState#OK} or {@link ReplayState#FAILED}.
      */
-    CommandDto commandDtoForReplay(final CommandLogEntry commandLogEntry) {
+    CommandDto commandDtoPossiblyRemappedForReplay(final CommandLogEntry commandLogEntry) {
         final CommandDto commandDto = copyCommandDto(commandLogEntry.getCommandDto());
         remapTargets(commandLogEntry, commandDto);
         remapReferenceParameters(commandLogEntry, commandDto);
diff --git a/extensions/core/commandlog/applib/src/test/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommandMappingTest.java b/extensions/core/commandlog/applib/src/test/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommandMappingTest.java
index 1e50da971e7..4608640af59 100644
--- a/extensions/core/commandlog/applib/src/test/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommandMappingTest.java
+++ b/extensions/core/commandlog/applib/src/test/java/org/apache/causeway/extensions/commandlog/applib/dom/replay/ReplayableCommandMappingTest.java
@@ -67,7 +67,7 @@ void target_remapping_changes_replay_command_dto() {
                 Bookmark.forLogicalTypeNameAndIdentifier("simple.SimpleObject", "1")))
                 .thenReturn(Optional.of(Bookmark.forLogicalTypeNameAndIdentifier("simple.SimpleObject", "2")));
 
-        CommandDto replayCommandDto = replayableCommand(listener).commandDtoForReplay(commandLogEntry);
+        CommandDto replayCommandDto = replayableCommand(listener).commandDtoPossiblyRemappedForReplay(commandLogEntry);
 
         assertThat(replayCommandDto.getTargets().getOid().get(0).getType()).isEqualTo("simple.SimpleObject");
         assertThat(replayCommandDto.getTargets().getOid().get(0).getId()).isEqualTo("2");
@@ -80,7 +80,7 @@ void missing_target_remapping_leaves_replay_command_dto_unchanged() {
         CommandLogEntry commandLogEntry = commandLogEntryWithCommandDto(recordedCommandDto);
         CommandReplayMappingListener listener = mock(CommandReplayMappingListener.class);
 
-        CommandDto replayCommandDto = replayableCommand(listener).commandDtoForReplay(commandLogEntry);
+        CommandDto replayCommandDto = replayableCommand(listener).commandDtoPossiblyRemappedForReplay(commandLogEntry);
 
         assertThat(replayCommandDto.getTargets().getOid().get(0).getId()).isEqualTo("1");
         assertThat(recordedCommandDto.getTargets().getOid().get(0).getId()).isEqualTo("1");
@@ -98,7 +98,7 @@ void reference_parameter_remapping_changes_replay_command_dto() {
                 Bookmark.forLogicalTypeNameAndIdentifier("simple.SimpleObject", "3")))
                 .thenReturn(Optional.of(Bookmark.forLogicalTypeNameAndIdentifier("simple.SimpleObject", "4")));
 
-        CommandDto replayCommandDto = replayableCommand(listener).commandDtoForReplay(commandLogEntry);
+        CommandDto replayCommandDto = replayableCommand(listener).commandDtoPossiblyRemappedForReplay(commandLogEntry);
         ParamDto replayParameter = ((ActionDto) replayCommandDto.getMember()).getParameters().getParameter().get(0);
         ParamDto recordedParameter = ((ActionDto) recordedCommandDto.getMember()).getParameters().getParameter().get(0);
 
@@ -113,7 +113,7 @@ void missing_reference_parameter_remapping_leaves_replay_command_dto_unchanged()
         CommandLogEntry commandLogEntry = commandLogEntryWithCommandDto(recordedCommandDto);
         CommandReplayMappingListener listener = mock(CommandReplayMappingListener.class);
 
-        CommandDto replayCommandDto = replayableCommand(listener).commandDtoForReplay(commandLogEntry);
+        CommandDto replayCommandDto = replayableCommand(listener).commandDtoPossiblyRemappedForReplay(commandLogEntry);
         ParamDto replayParameter = ((ActionDto) replayCommandDto.getMember()).getParameters().getParameter().get(0);
         ParamDto recordedParameter = ((ActionDto) recordedCommandDto.getMember()).getParameters().getParameter().get(0);
 
@@ -131,7 +131,7 @@ void non_reference_parameter_is_not_remapped_by_reference_flow() {
         CommandLogEntry commandLogEntry = commandLogEntryWithCommandDto(recordedCommandDto);
         CommandReplayMappingListener listener = mock(CommandReplayMappingListener.class);
 
-        CommandDto replayCommandDto = replayableCommand(listener).commandDtoForReplay(commandLogEntry);
+        CommandDto replayCommandDto = replayableCommand(listener).commandDtoPossiblyRemappedForReplay(commandLogEntry);
         ParamDto replayParameter = ((ActionDto) replayCommandDto.getMember()).getParameters().getParameter().get(0);
 
         assertThat(replayParameter.getString()).isEqualTo("unchanged");