FINERACT-1971: Enhanced error logging: Optimistic lock exception handling + log most specific exception
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/ErrorHandler.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/ErrorHandler.java
index 4ce0e98..f6ffb43 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/ErrorHandler.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/ErrorHandler.java
@@ -44,6 +44,7 @@
 import org.apache.fineract.infrastructure.core.exceptionmapper.DefaultExceptionMapper;
 import org.apache.fineract.infrastructure.core.exceptionmapper.FineractExceptionMapper;
 import org.apache.fineract.infrastructure.core.serialization.GoogleGsonSerializerHelper;
+import org.eclipse.persistence.exceptions.OptimisticLockException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.ApplicationContext;
 import org.springframework.core.NestedRuntimeException;
@@ -177,12 +178,17 @@
             if (nre instanceof NonTransientDataAccessException) {
                 msgCode = msgCode == null ? codePfx + ".data.integrity.issue" : msgCode;
                 return new PlatformDataIntegrityException(msgCode, msg, param, args);
+            } else if (cause instanceof OptimisticLockException) {
+                return (RuntimeException) cause;
             }
         }
         if (t instanceof ValidationException) {
             msgCode = msgCode == null ? codePfx + ".validation.error" : msgCode;
             return new PlatformApiDataValidationException(List.of(ApiParameterError.parameterError(msgCode, msg, param, defaultMsgArgs)));
         }
+        if (t instanceof jakarta.persistence.OptimisticLockException) {
+            return (RuntimeException) t;
+        }
         if (t instanceof PersistenceException) {
             msgCode = msgCode == null ? codePfx + ".persistence.error" : msgCode;
             return new PlatformDataIntegrityException(msgCode, msg, param, args);
@@ -191,13 +197,13 @@
             msgCode = msgCode == null ? codePfx + ".authentication.error" : msgCode;
             return new PlatformDataIntegrityException(msgCode, msg, param, args);
         }
-        if (t instanceof RuntimeException re) {
-            return re;
-        }
         if (t instanceof ParseException) {
             msgCode = msgCode == null ? codePfx + ".parse.error" : msgCode;
             return new PlatformDataIntegrityException(msgCode, msg, param, args);
         }
+        if (t instanceof RuntimeException re) {
+            return re;
+        }
         return new RuntimeException(msg, t);
     }
 
@@ -208,4 +214,12 @@
             return Set.of(array);
         }
     }
+
+    public static Throwable findMostSpecificException(Exception exception) {
+        Throwable mostSpecificException = exception;
+        while (mostSpecificException.getCause() != null) {
+            mostSpecificException = mostSpecificException.getCause();
+        }
+        return mostSpecificException;
+    }
 }
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/HttpMessageNotReadableErrorController.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/HttpMessageNotReadableErrorController.java
index bf04e8d..8bd56c3 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/HttpMessageNotReadableErrorController.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exception/HttpMessageNotReadableErrorController.java
@@ -39,7 +39,7 @@
     public Response toResponse(HttpMessageNotReadableException exception) {
         final String globalisationMessageCode = "error.msg.invalid.json.data";
         final String defaultUserMessage = "The referenced JSON data is invalid, validate date format as yyyy-MM-dd or other cases like String instead of Number";
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
 
         final ApiParameterError error = ApiParameterError.generalError(globalisationMessageCode, defaultUserMessage);
 
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/AccessDeniedExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/AccessDeniedExceptionMapper.java
index 4c944c2..d0738ce 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/AccessDeniedExceptionMapper.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/AccessDeniedExceptionMapper.java
@@ -25,6 +25,7 @@
 import jakarta.ws.rs.ext.Provider;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
 import org.springframework.context.annotation.Scope;
 import org.springframework.security.access.AccessDeniedException;
 import org.springframework.stereotype.Component;
@@ -46,7 +47,7 @@
         // Status code 403 really reads as:
         // "Authenticated - but not authorized":
         final String defaultUserMessage = exception.getMessage();
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
         return Response.status(Status.FORBIDDEN).entity(ApiGlobalErrorResponse.unAuthorized(defaultUserMessage))
                 .type(MediaType.APPLICATION_JSON).build();
     }
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BadCredentialsExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BadCredentialsExceptionMapper.java
index c00e846..a5314e4 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BadCredentialsExceptionMapper.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BadCredentialsExceptionMapper.java
@@ -25,6 +25,7 @@
 import jakarta.ws.rs.ext.Provider;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
 import org.springframework.context.annotation.Scope;
 import org.springframework.security.authentication.BadCredentialsException;
 import org.springframework.stereotype.Component;
@@ -44,7 +45,7 @@
 
     @Override
     public Response toResponse(@SuppressWarnings("unused") final BadCredentialsException exception) {
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
         return Response.status(Status.UNAUTHORIZED).entity(ApiGlobalErrorResponse.unAuthenticated()).type(MediaType.APPLICATION_JSON)
                 .build();
     }
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BusinessStepExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BusinessStepExceptionMapper.java
index 2943232..64111e9 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BusinessStepExceptionMapper.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BusinessStepExceptionMapper.java
@@ -25,6 +25,7 @@
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.cob.exceptions.BusinessStepException;
 import org.apache.fineract.infrastructure.core.data.ApiParameterError;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
 import org.springframework.stereotype.Component;
 
 @Provider
@@ -36,7 +37,7 @@
     public Response toResponse(BusinessStepException exception) {
         final String globalisationMessageCode = "error.msg.invalid.request.body";
         final String defaultUserMessage = exception.getMessage();
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
 
         final ApiParameterError error = ApiParameterError.parameterError(globalisationMessageCode, defaultUserMessage, "stepName");
 
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BusinessStepNotBelongsToJobExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BusinessStepNotBelongsToJobExceptionMapper.java
index 731fc5d..618b78e 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BusinessStepNotBelongsToJobExceptionMapper.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/BusinessStepNotBelongsToJobExceptionMapper.java
@@ -25,6 +25,7 @@
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.cob.exceptions.BusinessStepNotBelongsToJobException;
 import org.apache.fineract.infrastructure.core.data.ApiParameterError;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
 import org.springframework.stereotype.Component;
 
 @Provider
@@ -36,7 +37,7 @@
     public Response toResponse(BusinessStepNotBelongsToJobException exception) {
         final String globalisationMessageCode = "error.msg.invalid.request.body";
         final String defaultUserMessage = "One of the provided Business Steps does not belong to the provided Job Name.";
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
 
         final ApiParameterError error = ApiParameterError.generalError(globalisationMessageCode, defaultUserMessage);
 
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/ConcurrencyFailureExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/ConcurrencyFailureExceptionMapper.java
index 0d63157..bf3d6b3 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/ConcurrencyFailureExceptionMapper.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/ConcurrencyFailureExceptionMapper.java
@@ -26,6 +26,7 @@
 import jakarta.ws.rs.ext.Provider;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
 import org.springframework.context.annotation.Scope;
 import org.springframework.dao.ConcurrencyFailureException;
 import org.springframework.orm.ObjectOptimisticLockingFailureException;
@@ -43,7 +44,7 @@
 
     @Override
     public Response toResponse(final ConcurrencyFailureException exception) {
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
         String type;
         String identifier;
         if (exception instanceof ObjectOptimisticLockingFailureException olex) {
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/DefaultExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/DefaultExceptionMapper.java
index e6a283c..17c2fa0 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/DefaultExceptionMapper.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/DefaultExceptionMapper.java
@@ -26,6 +26,7 @@
 import java.util.Map;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
 import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Component;
 
@@ -41,7 +42,7 @@
 
     @Override
     public Response toResponse(RuntimeException exception) {
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
         return Response.status(SC_INTERNAL_SERVER_ERROR)
                 .entity(Map.of("Exception", ObjectUtils.defaultIfNull(exception.getMessage(), "No error message available")))
                 .type(MediaType.APPLICATION_JSON).build();
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/IdempotentCommandExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/IdempotentCommandExceptionMapper.java
index df17e3d..b969e4e 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/IdempotentCommandExceptionMapper.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/IdempotentCommandExceptionMapper.java
@@ -28,6 +28,7 @@
 import jakarta.ws.rs.ext.Provider;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.infrastructure.core.exception.AbstractIdempotentCommandException;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
 import org.apache.fineract.infrastructure.core.exception.IdempotentCommandProcessFailedException;
 import org.apache.fineract.infrastructure.core.exception.IdempotentCommandProcessSucceedException;
 import org.apache.fineract.infrastructure.core.exception.IdempotentCommandProcessUnderProcessingException;
@@ -46,7 +47,7 @@
 
     @Override
     public Response toResponse(final AbstractIdempotentCommandException exception) {
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
         Integer status = null;
         if (exception instanceof IdempotentCommandProcessSucceedException pse) {
             Integer statusCode = pse.getStatusCode();
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidInstanceTypeMethodExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidInstanceTypeMethodExceptionMapper.java
index dfae947..6fea992 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidInstanceTypeMethodExceptionMapper.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidInstanceTypeMethodExceptionMapper.java
@@ -25,6 +25,7 @@
 import jakarta.ws.rs.ext.Provider;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
 import org.apache.fineract.infrastructure.security.exception.InvalidInstanceTypeMethodException;
 import org.springframework.stereotype.Component;
 
@@ -39,7 +40,7 @@
 
     @Override
     public Response toResponse(final InvalidInstanceTypeMethodException exception) {
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
         ApiGlobalErrorResponse errorResponse = ApiGlobalErrorResponse.invalidInstanceTypeMethod(exception.getMethod());
         return Response.status(Status.METHOD_NOT_ALLOWED).entity(errorResponse).type(MediaType.APPLICATION_JSON).build();
     }
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidJsonExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidJsonExceptionMapper.java
index 35f0784..6461040 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidJsonExceptionMapper.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidJsonExceptionMapper.java
@@ -25,6 +25,7 @@
 import jakarta.ws.rs.ext.Provider;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.infrastructure.core.data.ApiParameterError;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
 import org.apache.fineract.infrastructure.core.exception.InvalidJsonException;
 import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Component;
@@ -42,7 +43,7 @@
     public Response toResponse(@SuppressWarnings("unused") final InvalidJsonException exception) {
         final String globalisationMessageCode = "error.msg.invalid.request.body";
         final String defaultUserMessage = "The JSON provided in the body of the request is invalid or missing.";
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
 
         final ApiParameterError error = ApiParameterError.generalError(globalisationMessageCode, defaultUserMessage);
 
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidTenantIdentifierExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidTenantIdentifierExceptionMapper.java
index 6751ed8..956f47c 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidTenantIdentifierExceptionMapper.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/InvalidTenantIdentifierExceptionMapper.java
@@ -25,6 +25,7 @@
 import jakarta.ws.rs.ext.Provider;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
 import org.apache.fineract.infrastructure.security.exception.InvalidTenantIdentifierException;
 import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Component;
@@ -44,7 +45,7 @@
 
     @Override
     public Response toResponse(@SuppressWarnings("unused") final InvalidTenantIdentifierException exception) {
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
         return Response.status(Status.UNAUTHORIZED).entity(ApiGlobalErrorResponse.invalidTenantIdentifier())
                 .type(MediaType.APPLICATION_JSON).build();
     }
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JakartaOptimisticLockExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JakartaOptimisticLockExceptionMapper.java
new file mode 100644
index 0000000..f773b2b
--- /dev/null
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JakartaOptimisticLockExceptionMapper.java
@@ -0,0 +1,56 @@
+/**
+ * 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.fineract.infrastructure.core.exceptionmapper;
+
+import static org.apache.http.HttpStatus.SC_CONFLICT;
+
+import jakarta.persistence.OptimisticLockException;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.ext.ExceptionMapper;
+import jakarta.ws.rs.ext.Provider;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
+import org.springframework.orm.ObjectOptimisticLockingFailureException;
+import org.springframework.stereotype.Component;
+
+/**
+ * An {@link ExceptionMapper} to map {@link ObjectOptimisticLockingFailureException} thrown by platform into a HTTP API
+ * friendly format.
+ */
+@Provider
+@Component
+@Slf4j
+public class JakartaOptimisticLockExceptionMapper implements FineractExceptionMapper, ExceptionMapper<OptimisticLockException> {
+
+    @Override
+    public Response toResponse(final OptimisticLockException exception) {
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
+        String type = "optimistic lock";
+        String identifier = "unknown";
+        final ApiGlobalErrorResponse dataIntegrityError = ApiGlobalErrorResponse.conflict(type, identifier);
+        return Response.status(SC_CONFLICT).entity(dataIntegrityError).type(MediaType.APPLICATION_JSON).build();
+    }
+
+    @Override
+    public int errorCode() {
+        return 4019;
+    }
+}
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JobIsNotFoundOrNotEnabledExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JobIsNotFoundOrNotEnabledExceptionMapper.java
index 73b71b3..2ff0be6 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JobIsNotFoundOrNotEnabledExceptionMapper.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JobIsNotFoundOrNotEnabledExceptionMapper.java
@@ -24,6 +24,7 @@
 import jakarta.ws.rs.ext.Provider;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
 import org.apache.fineract.infrastructure.core.exception.JobIsNotFoundOrNotEnabledException;
 import org.springframework.stereotype.Component;
 
@@ -34,7 +35,7 @@
 
     @Override
     public Response toResponse(JobIsNotFoundOrNotEnabledException exception) {
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
         return Response.status(Response.Status.FORBIDDEN)
                 .entity(ApiGlobalErrorResponse.jobIsDisabled(exception.getGlobalisationMessageCode(), exception.getDefaultUserMessage()))
                 .type(MediaType.APPLICATION_JSON).build();
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JpaOptimisticLockExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JpaOptimisticLockExceptionMapper.java
new file mode 100644
index 0000000..a236c44
--- /dev/null
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JpaOptimisticLockExceptionMapper.java
@@ -0,0 +1,56 @@
+/**
+ * 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.fineract.infrastructure.core.exceptionmapper;
+
+import static org.apache.http.HttpStatus.SC_CONFLICT;
+
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.ext.ExceptionMapper;
+import jakarta.ws.rs.ext.Provider;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
+import org.springframework.orm.ObjectOptimisticLockingFailureException;
+import org.springframework.orm.jpa.JpaOptimisticLockingFailureException;
+import org.springframework.stereotype.Component;
+
+/**
+ * An {@link ExceptionMapper} to map {@link ObjectOptimisticLockingFailureException} thrown by platform into a HTTP API
+ * friendly format.
+ */
+@Provider
+@Component
+@Slf4j
+public class JpaOptimisticLockExceptionMapper implements FineractExceptionMapper, ExceptionMapper<JpaOptimisticLockingFailureException> {
+
+    @Override
+    public Response toResponse(final JpaOptimisticLockingFailureException exception) {
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
+        String type = "optimistic lock";
+        String identifier = "unknown";
+        final ApiGlobalErrorResponse dataIntegrityError = ApiGlobalErrorResponse.conflict(type, identifier);
+        return Response.status(SC_CONFLICT).entity(dataIntegrityError).type(MediaType.APPLICATION_JSON).build();
+    }
+
+    @Override
+    public int errorCode() {
+        return 4019;
+    }
+}
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JsonPathExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JsonPathExceptionMapper.java
index 3ce0aff..7f8da34 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JsonPathExceptionMapper.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JsonPathExceptionMapper.java
@@ -25,6 +25,7 @@
 import jakarta.ws.rs.ext.Provider;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.infrastructure.core.data.ApiParameterError;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
 import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Component;
 
@@ -38,7 +39,7 @@
     public Response toResponse(JsonPathException exception) {
         final String globalisationMessageCode = "error.msg.invalid.json.path";
         final String defaultUserMessage = "The referenced JSON path is invalid.";
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
 
         final ApiParameterError error = ApiParameterError.generalError(globalisationMessageCode, defaultUserMessage);
 
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JsonSyntaxExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JsonSyntaxExceptionMapper.java
index f32e551..a9dfb05 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JsonSyntaxExceptionMapper.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/JsonSyntaxExceptionMapper.java
@@ -26,6 +26,7 @@
 import jakarta.ws.rs.ext.Provider;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.infrastructure.core.data.ApiParameterError;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
 import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Component;
 
@@ -42,7 +43,7 @@
     public Response toResponse(final JsonSyntaxException exception) {
         final String globalisationMessageCode = "error.msg.invalid.request.body";
         final String defaultUserMessage = "The JSON syntax provided in the body of the request is invalid: " + exception.getMessage();
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
 
         final ApiParameterError error = ApiParameterError.generalError(globalisationMessageCode, defaultUserMessage);
 
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/MalformedJsonExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/MalformedJsonExceptionMapper.java
index fd650c5..b85bcdc 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/MalformedJsonExceptionMapper.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/MalformedJsonExceptionMapper.java
@@ -26,6 +26,7 @@
 import jakarta.ws.rs.ext.Provider;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.infrastructure.core.data.ApiParameterError;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
 import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Component;
 
@@ -42,7 +43,7 @@
     public Response toResponse(@SuppressWarnings("unused") final MalformedJsonException exception) {
         final String globalisationMessageCode = "error.msg.invalid.request.body";
         final String defaultUserMessage = "The JSON provided in the body of the request is invalid or missing.";
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
 
         final ApiParameterError error = ApiParameterError.generalError(globalisationMessageCode, defaultUserMessage);
 
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/NoAuthorizationExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/NoAuthorizationExceptionMapper.java
index af35c83..facef9f 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/NoAuthorizationExceptionMapper.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/NoAuthorizationExceptionMapper.java
@@ -25,6 +25,7 @@
 import jakarta.ws.rs.ext.Provider;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
 import org.apache.fineract.infrastructure.security.exception.NoAuthorizationException;
 import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Component;
@@ -47,7 +48,7 @@
         // Status code 403 really reads as:
         // "Authenticated - but not authorized":
         final String defaultUserMessage = exception.getMessage();
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
         return Response.status(Status.FORBIDDEN).entity(ApiGlobalErrorResponse.unAuthorized(defaultUserMessage))
                 .type(MediaType.APPLICATION_JSON).build();
     }
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/OAuth2ExceptionEntryPoint.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/OAuth2ExceptionEntryPoint.java
index cb24785..451581d 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/OAuth2ExceptionEntryPoint.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/OAuth2ExceptionEntryPoint.java
@@ -24,6 +24,7 @@
 import jakarta.servlet.http.HttpServletResponse;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
 import org.springframework.security.core.AuthenticationException;
 import org.springframework.security.web.AuthenticationEntryPoint;
 
@@ -33,7 +34,7 @@
     @Override
     public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception)
             throws ServletException {
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
         ApiGlobalErrorResponse errorResponse = ApiGlobalErrorResponse.unAuthenticated();
         response.setContentType("application/json");
         response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/OptimisticLockExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/OptimisticLockExceptionMapper.java
index 0417fe5..b170c8d 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/OptimisticLockExceptionMapper.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/OptimisticLockExceptionMapper.java
@@ -26,8 +26,8 @@
 import jakarta.ws.rs.ext.Provider;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
 import org.eclipse.persistence.exceptions.OptimisticLockException;
-import org.springframework.context.annotation.Scope;
 import org.springframework.orm.ObjectOptimisticLockingFailureException;
 import org.springframework.stereotype.Component;
 
@@ -37,13 +37,12 @@
  */
 @Provider
 @Component
-@Scope("singleton")
 @Slf4j
 public class OptimisticLockExceptionMapper implements FineractExceptionMapper, ExceptionMapper<OptimisticLockException> {
 
     @Override
     public Response toResponse(final OptimisticLockException exception) {
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
         String type = exception.getQuery() == null ? "unknown" : "query";
         String identifier = "unknown";
         final ApiGlobalErrorResponse dataIntegrityError = ApiGlobalErrorResponse.conflict(type, identifier);
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformApiDataValidationExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformApiDataValidationExceptionMapper.java
index 0fb62b1..707bb84 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformApiDataValidationExceptionMapper.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformApiDataValidationExceptionMapper.java
@@ -25,6 +25,7 @@
 import jakarta.ws.rs.ext.Provider;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
 import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
 import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Component;
@@ -45,7 +46,7 @@
 
     @Override
     public Response toResponse(final PlatformApiDataValidationException exception) {
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
         final ApiGlobalErrorResponse dataValidationErrorResponse = ApiGlobalErrorResponse
                 .badClientRequest(exception.getGlobalisationMessageCode(), exception.getDefaultUserMessage(), exception.getErrors());
 
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformDataIntegrityExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformDataIntegrityExceptionMapper.java
index 54e6a2b..d67d3c5 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformDataIntegrityExceptionMapper.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformDataIntegrityExceptionMapper.java
@@ -25,6 +25,7 @@
 import jakarta.ws.rs.ext.Provider;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
 import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
 import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Component;
@@ -44,7 +45,7 @@
 
     @Override
     public Response toResponse(final PlatformDataIntegrityException exception) {
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
         final ApiGlobalErrorResponse dataIntegrityError = ApiGlobalErrorResponse.dataIntegrityError(exception.getGlobalisationMessageCode(),
                 exception.getDefaultUserMessage(), exception.getParameterName(), exception.getDefaultUserMessageArgs());
 
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformDomainRuleExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformDomainRuleExceptionMapper.java
index 9b7fac9..721bb49 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformDomainRuleExceptionMapper.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformDomainRuleExceptionMapper.java
@@ -26,6 +26,7 @@
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
 import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
 import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Component;
 
@@ -44,7 +45,7 @@
 
     @Override
     public Response toResponse(final AbstractPlatformDomainRuleException exception) {
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
         final ApiGlobalErrorResponse notFoundErrorResponse = ApiGlobalErrorResponse.domainRuleViolation(
                 exception.getGlobalisationMessageCode(), exception.getDefaultUserMessage(), exception.getDefaultUserMessageArgs());
         // request understood but not carried out due to it violating some
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformInternalServerExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformInternalServerExceptionMapper.java
index e0231f0..68f551b 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformInternalServerExceptionMapper.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformInternalServerExceptionMapper.java
@@ -25,6 +25,7 @@
 import jakarta.ws.rs.ext.Provider;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
 import org.apache.fineract.infrastructure.core.exception.PlatformInternalServerException;
 import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Component;
@@ -43,7 +44,7 @@
 
     @Override
     public Response toResponse(final PlatformInternalServerException exception) {
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
         final ApiGlobalErrorResponse notFoundErrorResponse = ApiGlobalErrorResponse.serverSideError(exception.getGlobalisationMessageCode(),
                 exception.getDefaultUserMessage(), exception.getDefaultUserMessageArgs());
         return Response.status(Status.INTERNAL_SERVER_ERROR).entity(notFoundErrorResponse).type(MediaType.APPLICATION_JSON).build();
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformRequestBodyItemLimitValidationExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformRequestBodyItemLimitValidationExceptionMapper.java
index c0a875c..4e67cb3 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformRequestBodyItemLimitValidationExceptionMapper.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformRequestBodyItemLimitValidationExceptionMapper.java
@@ -24,6 +24,7 @@
 import jakarta.ws.rs.ext.Provider;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
 import org.apache.fineract.infrastructure.core.exception.PlatformRequestBodyItemLimitValidationException;
 import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Component;
@@ -38,7 +39,7 @@
     @Override
     public Response toResponse(PlatformRequestBodyItemLimitValidationException exception) {
         String globalisationMessage = "error.msg.validation.request.body.item.limit.validation";
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
         final ApiGlobalErrorResponse badRequestErrorResponse = ApiGlobalErrorResponse.badClientRequest(globalisationMessage,
                 exception.getMessage());
         return Response.status(Response.Status.BAD_REQUEST).entity(badRequestErrorResponse).type(MediaType.APPLICATION_JSON).build();
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformResourceNotFoundExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformResourceNotFoundExceptionMapper.java
index 56ba364..bbdc005 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformResourceNotFoundExceptionMapper.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformResourceNotFoundExceptionMapper.java
@@ -26,6 +26,7 @@
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
 import org.apache.fineract.infrastructure.core.exception.AbstractPlatformResourceNotFoundException;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
 import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Component;
 
@@ -45,7 +46,7 @@
 
     @Override
     public Response toResponse(final AbstractPlatformResourceNotFoundException exception) {
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
         final ApiGlobalErrorResponse notFoundErrorResponse = ApiGlobalErrorResponse.notFound(exception.getGlobalisationMessageCode(),
                 exception.getDefaultUserMessage(), exception.getDefaultUserMessageArgs());
         return Response.status(Status.NOT_FOUND).entity(notFoundErrorResponse).type(MediaType.APPLICATION_JSON).build();
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformServiceUnavailableExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformServiceUnavailableExceptionMapper.java
index 38f4074..6248dc1 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformServiceUnavailableExceptionMapper.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/PlatformServiceUnavailableExceptionMapper.java
@@ -26,6 +26,7 @@
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
 import org.apache.fineract.infrastructure.core.exception.AbstractPlatformServiceUnavailableException;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
 import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Component;
 
@@ -45,7 +46,7 @@
 
     @Override
     public Response toResponse(final AbstractPlatformServiceUnavailableException exception) {
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
         final ApiGlobalErrorResponse serviceUnavailableExceptionResponse = ApiGlobalErrorResponse.serviceUnavailable(
                 exception.getGlobalisationMessageCode(), exception.getDefaultUserMessage(), exception.getDefaultUserMessageArgs());
         return Response.status(Status.SERVICE_UNAVAILABLE).entity(serviceUnavailableExceptionResponse).type(MediaType.APPLICATION_JSON)
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/RollbackTransactionNotApprovedExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/RollbackTransactionNotApprovedExceptionMapper.java
index 33087af..93f8b29 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/RollbackTransactionNotApprovedExceptionMapper.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/RollbackTransactionNotApprovedExceptionMapper.java
@@ -25,6 +25,7 @@
 import jakarta.ws.rs.ext.Provider;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.commands.exception.RollbackTransactionNotApprovedException;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
 import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
 import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Component;
@@ -45,7 +46,7 @@
 
     @Override
     public Response toResponse(final RollbackTransactionNotApprovedException exception) {
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
         return Response.ok().entity(new Gson().toJson(exception.getResult())).type(MediaType.APPLICATION_JSON).build();
     }
 
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnAuthenticatedUserExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnAuthenticatedUserExceptionMapper.java
index 0f979f0..2d9b00a 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnAuthenticatedUserExceptionMapper.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnAuthenticatedUserExceptionMapper.java
@@ -25,6 +25,7 @@
 import jakarta.ws.rs.ext.Provider;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
 import org.apache.fineract.useradministration.exception.UnAuthenticatedUserException;
 import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Component;
@@ -42,7 +43,7 @@
     @Override
     public Response toResponse(@SuppressWarnings("unused") final UnAuthenticatedUserException exception) {
         // Status code 401 really reads as: "Unauthenticated":
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
         return Response.status(Status.UNAUTHORIZED).entity(ApiGlobalErrorResponse.unAuthenticated()).type(MediaType.APPLICATION_JSON)
                 .build();
     }
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnrecognizedQueryParamExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnrecognizedQueryParamExceptionMapper.java
index e952a74..4bb4b21 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnrecognizedQueryParamExceptionMapper.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnrecognizedQueryParamExceptionMapper.java
@@ -28,6 +28,7 @@
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
 import org.apache.fineract.infrastructure.core.data.ApiParameterError;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
 import org.apache.fineract.infrastructure.core.exception.UnrecognizedQueryParamException;
 import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Component;
@@ -55,7 +56,7 @@
                 .append(parameterName) //
                 .append(" has an unsupported value of: ") //
                 .append(parameterValue);
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
 
         final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(), defaultEnglishMessage.toString(),
                 parameterName, parameterName, parameterValue, exception.getSupportedParams());
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnsupportedCommandExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnsupportedCommandExceptionMapper.java
index daaf720..387d6b8 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnsupportedCommandExceptionMapper.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnsupportedCommandExceptionMapper.java
@@ -29,6 +29,7 @@
 import org.apache.fineract.commands.exception.UnsupportedCommandException;
 import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
 import org.apache.fineract.infrastructure.core.data.ApiParameterError;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
 import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Component;
 
@@ -53,7 +54,7 @@
         if (message != null) {
             defaultEnglishMessage.append(" ").append(message);
         }
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
         final ApiParameterError error = ApiParameterError.parameterError(validationErrorCode.toString(), defaultEnglishMessage.toString(),
                 exception.getUnsupportedCommandName(), exception.getUnsupportedCommandName());
 
diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnsupportedParameterExceptionMapper.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnsupportedParameterExceptionMapper.java
index 65d515f..1309798 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnsupportedParameterExceptionMapper.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/UnsupportedParameterExceptionMapper.java
@@ -28,6 +28,7 @@
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.infrastructure.core.data.ApiGlobalErrorResponse;
 import org.apache.fineract.infrastructure.core.data.ApiParameterError;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
 import org.apache.fineract.infrastructure.core.exception.UnsupportedParameterException;
 import org.springframework.context.annotation.Scope;
 import org.springframework.stereotype.Component;
@@ -55,7 +56,7 @@
 
             errors.add(error);
         }
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
 
         final ApiGlobalErrorResponse invalidParameterError = ApiGlobalErrorResponse
                 .badClientRequest("validation.msg.validation.errors.exist", "Validation errors exist.", errors);
diff --git a/fineract-investor/src/main/java/org/apache/fineract/investor/exception/exceptionmapper/ExternalAssetOwnerInitiateTransferExceptionMapper.java b/fineract-investor/src/main/java/org/apache/fineract/investor/exception/exceptionmapper/ExternalAssetOwnerInitiateTransferExceptionMapper.java
index e10faba..243ac83 100644
--- a/fineract-investor/src/main/java/org/apache/fineract/investor/exception/exceptionmapper/ExternalAssetOwnerInitiateTransferExceptionMapper.java
+++ b/fineract-investor/src/main/java/org/apache/fineract/investor/exception/exceptionmapper/ExternalAssetOwnerInitiateTransferExceptionMapper.java
@@ -24,6 +24,7 @@
 import jakarta.ws.rs.ext.Provider;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.infrastructure.core.data.ApiParameterError;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
 import org.apache.fineract.investor.exception.ExternalAssetOwnerInitiateTransferException;
 import org.springframework.stereotype.Component;
 
@@ -36,7 +37,7 @@
     public Response toResponse(ExternalAssetOwnerInitiateTransferException exception) {
         final String globalisationMessageCode = "error.msg.external.asset.owner.initiate";
         final String defaultUserMessage = exception.getMessage();
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
 
         final ApiParameterError error = ApiParameterError.generalError(globalisationMessageCode, defaultUserMessage);
 
diff --git a/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exception/LinkedAccountRequiredExceptionMapper.java b/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exception/LinkedAccountRequiredExceptionMapper.java
index 8f24811..6af3fd2 100644
--- a/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exception/LinkedAccountRequiredExceptionMapper.java
+++ b/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exception/LinkedAccountRequiredExceptionMapper.java
@@ -35,7 +35,7 @@
 
     @Override
     public Response toResponse(LinkedAccountRequiredException exception) {
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
         final ApiGlobalErrorResponse notFoundErrorResponse = ApiGlobalErrorResponse.domainRuleViolation(
                 exception.getGlobalisationMessageCode(), exception.getDefaultUserMessage(), exception.getDefaultUserMessageArgs());
         // request understood but not carried out due to it violating some
diff --git a/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exception/LoanIdsHardLockedExceptionMapper.java b/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exception/LoanIdsHardLockedExceptionMapper.java
index 81f0743..23188bc 100644
--- a/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exception/LoanIdsHardLockedExceptionMapper.java
+++ b/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exception/LoanIdsHardLockedExceptionMapper.java
@@ -36,7 +36,7 @@
 
     @Override
     public Response toResponse(LoanIdsHardLockedException exception) {
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
         return Response.status(HttpStatus.SC_CONFLICT)
                 .entity(ApiGlobalErrorResponse.loanIsLocked(exception.getLoanIdFromRequest()).toJson()).type(MediaType.APPLICATION_JSON)
                 .build();
diff --git a/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exception/MultiDisbursementDataRequiredExceptionMapper.java b/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exception/MultiDisbursementDataRequiredExceptionMapper.java
index c8b6753..b598de2 100644
--- a/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exception/MultiDisbursementDataRequiredExceptionMapper.java
+++ b/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exception/MultiDisbursementDataRequiredExceptionMapper.java
@@ -36,7 +36,7 @@
 
     @Override
     public Response toResponse(MultiDisbursementDataRequiredException exception) {
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
         final ApiGlobalErrorResponse notFoundErrorResponse = ApiGlobalErrorResponse.domainRuleViolation(
                 exception.getGlobalisationMessageCode(), exception.getDefaultUserMessage(), exception.getDefaultUserMessageArgs());
         // request understood but not carried out due to it violating some
diff --git a/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/LoanAccountLockCannotBeOverruledExceptionMapper.java b/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/LoanAccountLockCannotBeOverruledExceptionMapper.java
index 3cdfd2e..9990f6f 100644
--- a/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/LoanAccountLockCannotBeOverruledExceptionMapper.java
+++ b/fineract-loan/src/main/java/org/apache/fineract/infrastructure/core/exceptionmapper/LoanAccountLockCannotBeOverruledExceptionMapper.java
@@ -25,6 +25,7 @@
 import lombok.extern.slf4j.Slf4j;
 import org.apache.fineract.cob.exceptions.LoanAccountLockCannotBeOverruledException;
 import org.apache.fineract.infrastructure.core.data.ApiParameterError;
+import org.apache.fineract.infrastructure.core.exception.ErrorHandler;
 import org.springframework.stereotype.Component;
 
 @Provider
@@ -36,7 +37,7 @@
     public Response toResponse(LoanAccountLockCannotBeOverruledException exception) {
         final String globalisationMessageCode = "error.msg.invalid.request.body";
         final String defaultUserMessage = exception.getMessage();
-        log.warn("Exception occurred", exception);
+        log.warn("Exception occurred", ErrorHandler.findMostSpecificException(exception));
 
         final ApiParameterError error = ApiParameterError.generalError(globalisationMessageCode, defaultUserMessage);
 
diff --git a/fineract-provider/src/main/resources/application.properties b/fineract-provider/src/main/resources/application.properties
index 81833a3..aa3e5f7 100644
--- a/fineract-provider/src/main/resources/application.properties
+++ b/fineract-provider/src/main/resources/application.properties
@@ -322,7 +322,7 @@
 resilience4j.retry.instances.executeCommand.wait-duration=${FINERACT_COMMAND_PROCESSING_RETRY_WAIT_DURATION:1s}
 resilience4j.retry.instances.executeCommand.enable-exponential-backoff=${FINERACT_COMMAND_PROCESSING_RETRY_ENABLE_EXPONENTIAL_BACKOFF:true}
 resilience4j.retry.instances.executeCommand.exponential-backoff-multiplier=${FINERACT_COMMAND_PROCESSING_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER:2}
-resilience4j.retry.instances.executeCommand.retryExceptions=${FINERACT_COMMAND_PROCESSING_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException,org.apache.fineract.infrastructure.core.exception.IdempotentCommandProcessUnderProcessingException}
+resilience4j.retry.instances.executeCommand.retryExceptions=${FINERACT_COMMAND_PROCESSING_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException,jakarta.persistence.OptimisticLockException,org.springframework.orm.jpa.JpaOptimisticLockingFailureException,org.apache.fineract.infrastructure.core.exception.IdempotentCommandProcessUnderProcessingException}
 
 resilience4j.retry.instances.processJobDetailForExecution.max-attempts=${FINERACT_PROCESS_JOB_DETAIL_RETRY_MAX_ATTEMPTS:3}
 resilience4j.retry.instances.processJobDetailForExecution.wait-duration=${FINERACT_PROCESS_JOB_DETAIL_RETRY_WAIT_DURATION:1s}
@@ -333,10 +333,10 @@
 resilience4j.retry.instances.recalculateInterest.wait-duration=${FINERACT_PROCESS_RECALCULATE_INTEREST_RETRY_WAIT_DURATION:1s}
 resilience4j.retry.instances.recalculateInterest.enable-exponential-backoff=${FINERACT_PROCESS_RECALCULATE_INTEREST_RETRY_ENABLE_EXPONENTIAL_BACKOFF:true}
 resilience4j.retry.instances.recalculateInterest.exponential-backoff-multiplier=${FINERACT_PROCESS_RECALCULATE_INTEREST_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER:2}
-resilience4j.retry.instances.recalculateInterest.retryExceptions=${FINERACT_PROCESS_RECALCULATE_INTEREST_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException}
+resilience4j.retry.instances.recalculateInterest.retryExceptions=${FINERACT_PROCESS_RECALCULATE_INTEREST_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException,jakarta.persistence.OptimisticLockException,org.springframework.orm.jpa.JpaOptimisticLockingFailureException}
 
 resilience4j.retry.instances.postInterest.max-attempts=${FINERACT_PROCESS_POST_INTEREST_RETRY_MAX_ATTEMPTS:3}
 resilience4j.retry.instances.postInterest.wait-duration=${FINERACT_PROCESS_POST_INTEREST_RETRY_WAIT_DURATION:1s}
 resilience4j.retry.instances.postInterest.enable-exponential-backoff=${FINERACT_PROCESS_POST_INTEREST_RETRY_ENABLE_EXPONENTIAL_BACKOFF:true}
 resilience4j.retry.instances.postInterest.exponential-backoff-multiplier=${FINERACT_PROCESS_POST_INTEREST_RETRY_EXPONENTIAL_BACKOFF_MULTIPLIER:2}
-resilience4j.retry.instances.postInterest.retryExceptions=${FINERACT_PROCESS_POST_INTEREST_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException}
+resilience4j.retry.instances.postInterest.retryExceptions=${FINERACT_PROCESS_POST_INTEREST_RETRY_EXCEPTIONS:org.springframework.dao.ConcurrencyFailureException,org.eclipse.persistence.exceptions.OptimisticLockException,jakarta.persistence.OptimisticLockException,org.springframework.orm.jpa.JpaOptimisticLockingFailureException}