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

adamsaghy pushed a commit to branch release/1.13.1
in repository https://gitbox.apache.org/repos/asf/fineract.git

commit e3096c7ef060484efcc5104e378a8bff17969f29
Author: Adam Saghy <[email protected]>
AuthorDate: Tue Oct 21 15:29:09 2025 +0200

    FINERACT-2396: Fix retry issue during persisting CommandSource
---
 .../commands/service/SynchronousCommandProcessingService.java     | 8 ++++----
 .../commands/service/SynchronousCommandProcessingServiceTest.java | 6 ++++++
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git 
a/fineract-core/src/main/java/org/apache/fineract/commands/service/SynchronousCommandProcessingService.java
 
b/fineract-core/src/main/java/org/apache/fineract/commands/service/SynchronousCommandProcessingService.java
index 43647f426a..a13835b626 100644
--- 
a/fineract-core/src/main/java/org/apache/fineract/commands/service/SynchronousCommandProcessingService.java
+++ 
b/fineract-core/src/main/java/org/apache/fineract/commands/service/SynchronousCommandProcessingService.java
@@ -30,6 +30,7 @@ import java.time.Instant;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Supplier;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
@@ -166,13 +167,12 @@ public class SynchronousCommandProcessingService 
implements CommandProcessingSer
 
         try {
             CommandSource finalCommandSource = commandSource;
+            AtomicInteger attemptNumber = new AtomicInteger(0);
             CommandSource savedCommandSource = 
persistenceRetry.executeSupplier(() -> {
-                // Get metrics for logging
-                long attemptNumber = 
persistenceRetry.getMetrics().getNumberOfFailedCallsWithRetryAttempt() + 1;
-
                 // Critical: Refetch on retry attempts (not on first attempt)
                 CommandSource currentSource = finalCommandSource;
-                if (attemptNumber > 1) {
+                attemptNumber.getAndIncrement();
+                if (attemptNumber.get() > 1 && commandSource.getId() != null) {
                     log.info("Retrying command result save - attempt {} for 
command ID {}", attemptNumber, finalCommandSource.getId());
                     currentSource = 
commandSourceService.getCommandSource(finalCommandSource.getId());
                 }
diff --git 
a/fineract-provider/src/test/java/org/apache/fineract/commands/service/SynchronousCommandProcessingServiceTest.java
 
b/fineract-provider/src/test/java/org/apache/fineract/commands/service/SynchronousCommandProcessingServiceTest.java
index 4e71ae7954..7bcb2b7d4f 100644
--- 
a/fineract-provider/src/test/java/org/apache/fineract/commands/service/SynchronousCommandProcessingServiceTest.java
+++ 
b/fineract-provider/src/test/java/org/apache/fineract/commands/service/SynchronousCommandProcessingServiceTest.java
@@ -591,5 +591,11 @@ public class SynchronousCommandProcessingServiceTest {
         assertEquals(persistentException, exception.getCause());
 
         assertTrue(saveAttempts.get() >= 3, "Expected at least 3 save 
attempts, but got: " + saveAttempts.get());
+        // First call was before saving CommandSource, then 2 calls during 
retry (1st retry does not try to fetch it)
+        verify(commandSourceService, times(3)).getCommandSource(commandId);
+        // Let test whether consecutive calls does not try to refetch 
immediately
+        
when(commandSourceService.saveResultSameTransaction(any(CommandSource.class))).thenReturn(commandSource);
+        underTest.executeCommand(commandWrapper, jsonCommand, false);
+        verify(commandSourceService, times(4)).getCommandSource(commandId);
     }
 }

Reply via email to