diff --git a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/tenant/JdbcTenantDetailsService.java b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/tenant/JdbcTenantDetailsService.java
index 3cc6167ed..e248b301a 100644
--- a/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/tenant/JdbcTenantDetailsService.java
+++ b/fineract-core/src/main/java/org/apache/fineract/infrastructure/core/service/tenant/JdbcTenantDetailsService.java
@@ -35,7 +35,7 @@ import org.springframework.stereotype.Service;
* A JDBC implementation of {@link TenantDetailsService} for loading a tenants details by a
* tenantIdentifier.
*/
-@Service
+@Service("tenantDetailsService")
public class JdbcTenantDetailsService implements TenantDetailsService {
private final JdbcTemplate jdbcTemplate;
diff --git a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/domain/MoneyHelper.java b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/domain/MoneyHelper.java
index f605f8e8d..10e55688d 100644
--- a/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/domain/MoneyHelper.java
+++ b/fineract-core/src/main/java/org/apache/fineract/organisation/monetary/domain/MoneyHelper.java
@@ -33,7 +33,6 @@ import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
public final class MoneyHelper {
public static final int PRECISION = 19;
- private static final RoundingMode DEFAULT_ROUNDING_MODE = RoundingMode.HALF_EVEN;
private static final ConcurrentHashMap roundingModeCache = new ConcurrentHashMap<>();
private static final ConcurrentHashMap mathContextCache = new ConcurrentHashMap<>();
@@ -62,7 +61,7 @@ public final class MoneyHelper {
// Clear math context cache to force recreation with new rounding mode
mathContextCache.remove(tenantIdentifier);
- log.info("Initialized rounding mode for tenant {}: {}", tenantIdentifier, roundingMode.name());
+ log.info("Initialized rounding mode for tenant `{}`: {}", tenantIdentifier, roundingMode.name());
}
/**
@@ -77,9 +76,7 @@ public final class MoneyHelper {
RoundingMode roundingMode = roundingModeCache.get(tenantId);
if (roundingMode == null) {
- // For integration tests and development, use default if not initialized
- log.warn("Rounding mode not initialized for tenant: {}. Using default: {}", tenantId, DEFAULT_ROUNDING_MODE);
- return DEFAULT_ROUNDING_MODE;
+ throw new IllegalStateException("Rounding mode is not initialized for tenant: " + tenantId);
}
return roundingMode;
}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/service/MoneyHelperInitializationService.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/service/MoneyHelperInitializationService.java
index 617ef4a28..04eac2f3d 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/service/MoneyHelperInitializationService.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/service/MoneyHelperInitializationService.java
@@ -18,7 +18,6 @@
*/
package org.apache.fineract.infrastructure.configuration.service;
-import java.math.RoundingMode;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.configuration.api.GlobalConfigurationConstants;
@@ -66,9 +65,6 @@ public class MoneyHelperInitializationService {
// Initialize MoneyHelper for this tenant
MoneyHelper.initializeTenantRoundingMode(tenantIdentifier, roundingModeValue);
-
- log.info("MoneyHelper initialized for tenant '{}' with rounding mode: {}", tenantIdentifier, roundingModeValue);
-
} catch (Exception e) {
log.error("Failed to initialize MoneyHelper for tenant '{}'", tenantIdentifier, e);
throw new RuntimeException("Failed to initialize MoneyHelper for tenant: " + tenantIdentifier, e);
@@ -90,26 +86,13 @@ public class MoneyHelperInitializationService {
}
/**
- * Get the rounding mode from configuration with fallback to default. This method safely handles cases where
- * configuration might not be available.
+ * Get the rounding mode from configuration with fallback to default.
*
* @return the rounding mode value
*/
private int getRoundingModeFromConfiguration() {
- try {
- GlobalConfigurationProperty roundingModeProperty = globalConfigurationRepository
- .findOneByNameWithNotFoundDetection(GlobalConfigurationConstants.ROUNDING_MODE);
-
- if (roundingModeProperty != null && roundingModeProperty.getValue() != null) {
- return roundingModeProperty.getValue().intValue();
- }
- } catch (Exception e) {
- log.warn("Failed to read rounding mode from configuration: {}", e.getMessage());
- }
-
- // Default to HALF_UP if configuration is not available
- int defaultRoundingMode = RoundingMode.HALF_UP.ordinal();
- log.info("Using default rounding mode: {} (HALF_UP)", defaultRoundingMode);
- return defaultRoundingMode;
+ GlobalConfigurationProperty roundingModeProperty = globalConfigurationRepository
+ .findOneByNameWithNotFoundDetection(GlobalConfigurationConstants.ROUNDING_MODE);
+ return roundingModeProperty.getValue().intValue();
}
}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/service/MoneyHelperStartupInitializationService.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/service/MoneyHelperStartupInitializationService.java
index 7215d9616..bdef68fa6 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/service/MoneyHelperStartupInitializationService.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/service/MoneyHelperStartupInitializationService.java
@@ -23,9 +23,8 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant;
import org.apache.fineract.infrastructure.core.service.tenant.TenantDetailsService;
-import org.springframework.boot.context.event.ApplicationReadyEvent;
-import org.springframework.context.event.EventListener;
-import org.springframework.core.annotation.Order;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Service;
/**
@@ -35,7 +34,8 @@ import org.springframework.stereotype.Service;
@Service
@Slf4j
@RequiredArgsConstructor
-public class MoneyHelperStartupInitializationService {
+@DependsOn({ "tenantDetailsService", "moneyHelperInitializationService", "tenantDatabaseUpgradeService" })
+public class MoneyHelperStartupInitializationService implements InitializingBean {
private final TenantDetailsService tenantDetailsService;
private final MoneyHelperInitializationService moneyHelperInitializationService;
@@ -43,54 +43,30 @@ public class MoneyHelperStartupInitializationService {
/**
* Initialize MoneyHelper for all tenants after the application is ready. This method runs after
* ApplicationReadyEvent to ensure all database migrations and tenant configurations are complete.
+ *
+ * If it fails (for any reason), it will fail the application startup!
+ *
*/
- @EventListener(ApplicationReadyEvent.class)
- @Order(1000) // Run after other startup processes
- public void initializeMoneyHelperForAllTenants() {
+ @Override
+ public void afterPropertiesSet() throws Exception {
log.info("Starting MoneyHelper initialization for all tenants...");
- try {
- List tenants = tenantDetailsService.findAllTenants();
-
- if (tenants.isEmpty()) {
- log.warn("No tenants found during MoneyHelper initialization");
- return;
- }
-
- int successCount = 0;
- int failureCount = 0;
-
- for (FineractPlatformTenant tenant : tenants) {
- try {
- String tenantIdentifier = tenant.getTenantIdentifier();
-
- // Check if already initialized (in case of restart scenarios)
- if (moneyHelperInitializationService.isTenantInitialized(tenantIdentifier)) {
- log.debug("MoneyHelper already initialized for tenant: {}", tenantIdentifier);
- successCount++;
- continue;
- }
-
- // Initialize MoneyHelper for this tenant
- moneyHelperInitializationService.initializeTenantRoundingMode(tenant);
- successCount++;
-
- } catch (Exception e) {
- failureCount++;
- log.error("Failed to initialize MoneyHelper for tenant '{}'", tenant.getTenantIdentifier(), e);
- }
- }
-
- log.info("MoneyHelper initialization completed - Success: {}, Failures: {}, Total: {}", successCount, failureCount,
- tenants.size());
-
- if (failureCount > 0) {
- log.warn("Some tenants failed MoneyHelper initialization. "
- + "These tenants may experience issues with rounding mode configuration.");
- }
-
- } catch (Exception e) {
- log.error("Critical error during MoneyHelper initialization for all tenants", e);
+ List tenants = tenantDetailsService.findAllTenants();
+ if (tenants.isEmpty()) {
+ log.warn("No tenants found during MoneyHelper initialization");
+ return;
}
+
+ for (FineractPlatformTenant tenant : tenants) {
+ String tenantIdentifier = tenant.getTenantIdentifier();
+ // Check if already initialized (in case of restart scenarios)
+ if (moneyHelperInitializationService.isTenantInitialized(tenantIdentifier)) {
+ log.debug("MoneyHelper already initialized for tenant: {}", tenantIdentifier);
+ continue;
+ }
+ // Initialize MoneyHelper for this tenant
+ moneyHelperInitializationService.initializeTenantRoundingMode(tenant);
+ }
+ log.info("MoneyHelper initialization completed");
}
}