[ 
https://issues.apache.org/jira/browse/FINERACT-2559?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Adam Saghy resolved FINERACT-2559.
----------------------------------
    Fix Version/s: 1.15.0
       Resolution: Fixed

> Loan product details retrieval executes redundant DB query in classification 
> mapping flow
> -----------------------------------------------------------------------------------------
>
>                 Key: FINERACT-2559
>                 URL: https://issues.apache.org/jira/browse/FINERACT-2559
>             Project: Apache Fineract
>          Issue Type: Bug
>          Components: Accounting
>    Affects Versions: 1.14.0
>            Reporter: HuangXi
>            Priority: Major
>              Labels: database, performance, query-optimization
>             Fix For: 1.15.0
>
>   Original Estimate: 2h
>  Remaining Estimate: 2h
>
> *Problem* In the loan product details read path, the classification mapping 
> flow executes an additional repository query whose result is immediately 
> discarded. This creates an unnecessary database round trip with no functional 
> benefit.
> *Code location*
>  * Discarded query call: 
> {{fineract-accounting/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/service/ProductToGLAccountMappingReadPlatformServiceImpl.java}}
>  * Repository query definition: 
> {{fineract-accounting/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/domain/ProductToGLAccountMappingRepository.java}}
>  * Upstream API entry point: 
> {{fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/api/LoanProductsApiResource.java}}
> *Relevant code*
>  private List<ClassificationToGLAccountData> fetchClassificationMappings(
>          final PortfolioProductType portfolioProductType,
>          final Long loanProductId,
>          LoanProductAccountingParams classificationParameter) {
>  ​
>      final List<ProductToGLAccountMapping> mappings = classificationParameter
>              
> .equals(LoanProductAccountingParams.CAPITALIZED_INCOME_CLASSIFICATION_TO_INCOME_ACCOUNT_MAPPINGS)
>                      ? 
> productToGLAccountMappingRepository.findAllCapitalizedIncomeClassificationsMappings(
>                              loanProductId, portfolioProductType.getValue())
>                      : 
> productToGLAccountMappingRepository.findAllBuyDownFeeClassificationsMappings(
>                              loanProductId, portfolioProductType.getValue());
>  ​
>      productToGLAccountMappingRepository.findAllChargeOffReasonsMappings(
>              loanProductId, portfolioProductType.getValue());
>  ​
>      List<ClassificationToGLAccountData> classificationToGLAccountMappers = 
> mappings.isEmpty() ? null : new ArrayList<>();
>      for (final ProductToGLAccountMapping mapping : mappings) {
>          ...
>      }
>      return classificationToGLAccountMappers;
>  }
>  @Query("select mapping from ProductToGLAccountMapping mapping " +
>         "where mapping.productId = :productId and mapping.productType = 
> :productType " +
>         "and mapping.chargeOffReason is not NULL")
>  List<ProductToGLAccountMapping> findAllChargeOffReasonsMappings(
>          @Param("productId") Long productId,
>          @Param("productType") int productType);
> *Why this is a database performance issue*
>  * The repository method is a pure {{select}} query.
>  * Its return value is not assigned, checked, logged, or otherwise consumed.
>  * There is no visible side-effect semantics such as update, delete, lock 
> acquisition, or entity callback usage.
>  * The method continues to build the response only from {{mappings}}, which 
> come from the classification queries.
> Therefore, this query adds database load, object materialization, and 
> response-time overhead without any business value.
> *Impact* When loan product details are retrieved for accounting-enabled 
> products, this redundant query is executed in the classification mapping flow 
> even though its result is unused. This causes avoidable database round trips 
> and unnecessary performance overhead in a read-heavy path.
> *Expected result* Only functionally required queries should be executed 
> during loan product details retrieval.
> *Actual result* An extra charge-off-reason mapping query is executed in the 
> classification mapping flow, and its result is discarded.
> *Likely root cause* This appears to be leftover or copy-pasted code in the 
> classification mapping read path, rather than intentional logic.
> *Proposed fix* Remove the unused call to:
>  productToGLAccountMappingRepository.findAllChargeOffReasonsMappings(
>          loanProductId, portfolioProductType.getValue());
> *Validation*
>  * Loan product details response payload should remain unchanged.
>  * SQL logs should show one fewer unnecessary query execution in this 
> classification path.
>  * Charge-off reason mapping retrieval in its actual usage path should remain 
> unaffected.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to