From 9d7f1c2197dff20b4a977b77670b04e26cfcc2e1 Mon Sep 17 00:00:00 2001 From: Nazeer Hussain Shaik Date: Mon, 17 Oct 2016 11:46:52 +0530 Subject: [PATCH] OpenJPA Integration Changes --- fineract-provider/build.gradle | 22 +++--- fineract-provider/dependencies.gradle | 4 +- fineract-provider/dev-dependencies.gradle | 4 +- .../common/ProvisioningIntegrationTest.java | 26 +++++-- .../closure/domain/GLClosureRepository.java | 2 +- .../domain/FinancialActivityAccount.java | 4 +- .../FinancialActivityAccountRepository.java | 2 +- ...tivityAccountWritePlatformServiceImpl.java | 18 ++++- .../glaccount/domain/GLAccount.java | 6 +- .../domain/JournalEntryRepository.java | 12 +-- .../domain/ProductToGLAccountMapping.java | 17 ++--- .../ProductToGLAccountMappingRepository.java | 8 +- .../domain/LoanProductProvisioningEntry.java | 4 +- .../domain/ProvisioningEntry.java | 6 +- .../domain/ProvisioningEntryRepository.java | 5 +- .../rule/domain/AccountingRule.java | 6 +- .../rule/domain/AccountingRuleRepository.java | 2 +- .../rule/domain/AccountingTagRule.java | 4 +- .../batch/exception/ErrorHandler.java | 3 + .../batch/service/BatchApiServiceImpl.java | 18 ++++- .../commands/domain/CommandSource.java | 4 +- .../domain/AccountNumberFormat.java | 6 +- .../domain/AccountNumberFormatRepository.java | 2 +- ...WritePlatformServiceJpaRepositoryImpl.java | 22 ++++-- .../cache/domain/PlatformCache.java | 4 +- .../infrastructure/codes/domain/Code.java | 6 +- .../codes/domain/CodeValue.java | 4 +- ...WritePlatformServiceJpaRepositoryImpl.java | 20 +++-- .../configuration/domain/ExternalService.java | 4 +- .../domain/ExternalServicePropertiesPK.java | 28 +++++++ .../domain/ExternalServicesProperties.java | 2 - .../ExternalServicesPropertiesRepository.java | 5 +- ...alServicesPropertiesRepositoryWrapper.java | 2 +- .../domain/GlobalConfigurationProperty.java | 8 +- .../core/data/ApiParameterError.java | 11 ++- .../core/domain/AbstractAuditableCustom.java | 21 +++--- .../domain/AbstractPersistableCustom.java | 70 ++++++++++++++++++ .../core/domain/MySQLDictionaryCustom.java | 46 ++++++++++++ .../TomcatJdbcDataSourcePerTenantService.java | 3 +- .../dataqueries/domain/Report.java | 6 +- .../dataqueries/domain/ReportParameter.java | 4 +- .../domain/ReportParameterUsage.java | 10 +-- .../ReadWriteNonCoreDataServiceImpl.java | 72 +++++++++++++++++- .../ReportWritePlatformServiceImpl.java | 20 +++-- .../documentmanagement/domain/Document.java | 4 +- .../documentmanagement/domain/Image.java | 4 +- .../domain/FineractEntityAccess.java | 4 +- .../domain/FineractEntityRelation.java | 4 +- .../FineractEntityRelationRepository.java | 2 +- .../domain/FineractEntityToEntityMapping.java | 8 +- ...neractEntityToEntityMappingRepository.java | 2 +- .../FineractEntityAccessWriteServiceImpl.java | 20 +++-- .../hooks/domain/HookConfiguration.java | 4 +- .../hooks/domain/HookRepository.java | 4 +- .../hooks/domain/HookResource.java | 4 +- .../hooks/domain/HookTemplate.java | 6 +- .../hooks/domain/HookTemplateRepository.java | 2 +- .../infrastructure/hooks/domain/Schema.java | 6 +- ...WritePlatformServiceJpaRepositoryImpl.java | 60 ++++++++++----- .../jobs/domain/ScheduledJobDetail.java | 4 +- .../domain/ScheduledJobDetailRepository.java | 6 +- .../jobs/domain/ScheduledJobRunHistory.java | 4 +- .../jobs/domain/SchedulerDetail.java | 4 +- .../domain/ReportMailingJobConfiguration.java | 4 +- .../domain/ReportMailingJobRunHistory.java | 4 +- .../infrastructure/sms/domain/SmsMessage.java | 4 +- .../survey/domain/Likelihood.java | 4 +- .../survey/domain/LikelihoodRepository.java | 2 +- .../mix/domain/MixTaxonomyMapping.java | 4 +- .../organisation/holiday/domain/Holiday.java | 4 +- .../holiday/domain/HolidayRepository.java | 2 +- ...WritePlatformServiceJpaRepositoryImpl.java | 18 ++++- .../monetary/domain/ApplicationCurrency.java | 16 ++-- .../monetary/domain/MonetaryCurrency.java | 6 +- .../organisation/monetary/domain/Money.java | 8 +- .../organisation/office/domain/Office.java | 6 +- .../office/domain/OfficeTransaction.java | 4 +- .../office/domain/OrganisationCurrency.java | 16 ++-- ...WritePlatformServiceJpaRepositoryImpl.java | 18 ++++- .../domain/LoanProductProvisionCriteria.java | 4 +- .../domain/ProvisioningCategory.java | 4 +- .../domain/ProvisioningCriteria.java | 2 +- .../ProvisioningCriteriaDefinition.java | 5 +- ...WritePlatformServiceJpaRepositoryImpl.java | 18 ++++- ...WritePlatformServiceJpaRepositoryImpl.java | 21 ++++-- .../organisation/staff/domain/Staff.java | 18 +++-- ...WritePlatformServiceJpaRepositoryImpl.java | 18 ++++- .../organisation/teller/domain/Cashier.java | 4 +- .../teller/domain/CashierTransaction.java | 8 +- .../organisation/teller/domain/Teller.java | 30 +++----- .../domain/TellerRepositoryWrapper.java | 15 ++++ .../teller/domain/TellerTransaction.java | 4 +- .../TellerWritePlatformServiceJpaImpl.java | 68 ++++++++++------- .../workingdays/domain/WorkingDays.java | 4 +- .../account/domain/AccountAssociations.java | 4 +- .../domain/AccountAssociationsRepository.java | 4 +- .../domain/AccountTransferDetails.java | 8 +- .../domain/AccountTransferRepository.java | 8 +- .../AccountTransferStandingInstruction.java | 4 +- .../domain/AccountTransferTransaction.java | 4 +- .../portfolio/address/domain/Address.java | 4 +- .../address/domain/FieldConfiguration.java | 4 +- .../calendar/domain/CalendarHistory.java | 4 +- .../calendar/domain/CalendarInstance.java | 4 +- .../domain/CalendarInstanceRepository.java | 4 +- .../portfolio/charge/domain/Charge.java | 4 +- .../ChargeReadPlatformServiceImpl.java | 33 +++++---- ...WritePlatformServiceJpaRepositoryImpl.java | 20 +++-- .../portfolio/client/domain/Client.java | 18 ++--- .../client/domain/ClientAddress.java | 4 +- .../portfolio/client/domain/ClientCharge.java | 4 +- .../client/domain/ClientChargePaidBy.java | 4 +- .../client/domain/ClientNonPerson.java | 4 +- .../domain/ClientNonPersonRepository.java | 2 +- .../client/domain/ClientTransaction.java | 4 +- .../ClientTransactionRepositoryWrapper.java | 2 +- ...WritePlatformServiceJpaRepositoryImpl.java | 3 +- ...WritePlatformServiceJpaRepositoryImpl.java | 25 +++++-- ...WritePlatformServiceJpaRepositoryImpl.java | 24 ++++-- .../collateral/domain/LoanCollateral.java | 10 +-- .../floatingrates/domain/FloatingRate.java | 43 ++++------- .../domain/FloatingRatePeriod.java | 9 ++- .../domain/FloatingRateRepository.java | 10 +-- .../FloatingRateWritePlatformServiceImpl.java | 22 ++++-- .../fineract/portfolio/fund/domain/Fund.java | 4 +- ...WritePlatformServiceJpaRepositoryImpl.java | 19 +++-- .../portfolio/group/domain/Group.java | 8 +- .../portfolio/group/domain/GroupLevel.java | 10 +-- .../portfolio/group/domain/GroupRole.java | 4 +- ...WritePlatformServiceJpaRepositoryImpl.java | 28 +++++-- .../domain/InterestIncentives.java | 4 +- .../domain/InterestRateChart.java | 6 +- .../domain/InterestRateChartFields.java | 2 +- .../domain/InterestRateChartSlab.java | 6 +- .../domain/InterestRateChartSlabFields.java | 2 +- .../portfolio/loanaccount/domain/Loan.java | 73 ++++++++++++++++--- .../loanaccount/domain/LoanCharge.java | 21 +++--- .../loanaccount/domain/LoanChargePaidBy.java | 4 +- .../domain/LoanDisbursementDetails.java | 4 +- .../domain/LoanInstallmentCharge.java | 4 +- ...nterestRecalcualtionAdditionalDetails.java | 4 +- .../LoanInterestRecalculationDetails.java | 4 +- .../domain/LoanOverdueInstallmentCharge.java | 4 +- .../LoanRepaymentScheduleInstallment.java | 3 +- .../loanaccount/domain/LoanRepository.java | 34 ++++----- .../domain/LoanRepositoryWrapper.java | 1 + ...scheduleRequestToTermVariationMapping.java | 5 +- .../domain/LoanTermVariations.java | 5 +- .../loanaccount/domain/LoanTopupDetails.java | 15 ++-- .../loanaccount/domain/LoanTrancheCharge.java | 4 +- .../domain/LoanTrancheDisbursementCharge.java | 5 +- .../loanaccount/domain/LoanTransaction.java | 18 ++--- ...TransactionToRepaymentScheduleMapping.java | 4 +- .../guarantor/domain/Guarantor.java | 6 +- .../domain/GuarantorFundingDetails.java | 6 +- .../domain/GuarantorFundingTransaction.java | 4 +- ...GuarantorFundingTransactionRepository.java | 2 +- .../domain/AbstractLoanScheduleGenerator.java | 50 ++++++------- .../domain/LoanRepaymentScheduleHistory.java | 4 +- .../domain/LoanRescheduleRequest.java | 4 +- ...WritePlatformServiceJpaRepositoryImpl.java | 28 ++++--- .../service/LoanArrearsAgingServiceImpl.java | 1 - .../service/LoanChargeAssembler.java | 11 ++- .../loanproduct/domain/LoanProduct.java | 6 +- .../LoanProductBorrowerCycleVariations.java | 4 +- .../LoanProductConfigurableAttributes.java | 6 +- .../domain/LoanProductFloatingRates.java | 4 +- .../domain/LoanProductGuaranteeDetails.java | 8 +- ...anProductInterestRecalculationDetails.java | 4 +- .../domain/LoanProductTrancheDetails.java | 4 +- .../LoanProductVariableInstallmentConfig.java | 4 +- .../LoanTransactionProcessingStrategy.java | 4 +- .../productmix/domain/ProductMix.java | 4 +- .../domain/ProductMixRepository.java | 4 +- ...WritePlatformServiceJpaRepositoryImpl.java | 27 ++++--- .../attendance/domain/ClientAttendance.java | 4 +- .../portfolio/meeting/domain/Meeting.java | 4 +- .../fineract/portfolio/note/domain/Note.java | 4 +- .../paymentdetail/domain/PaymentDetail.java | 4 +- .../paymenttype/domain/PaymentType.java | 4 +- .../DepositAccountInterestIncentive.java | 4 +- .../DepositAccountInterestIncentives.java | 4 +- .../DepositAccountInterestRateChart.java | 4 +- .../DepositAccountInterestRateChartSlabs.java | 4 +- .../DepositAccountOnHoldTransaction.java | 4 +- .../domain/DepositAccountRecurringDetail.java | 8 +- .../DepositAccountTermAndPreClosure.java | 6 +- .../domain/DepositProductRecurringDetail.java | 4 +- .../DepositProductTermAndPreClosure.java | 4 +- .../savings/domain/FixedDepositAccount.java | 6 ++ .../domain/RecurringDepositAccount.java | 1 + .../RecurringDepositScheduleInstallment.java | 6 +- .../savings/domain/SavingsAccount.java | 10 +-- .../savings/domain/SavingsAccountCharge.java | 13 +--- .../domain/SavingsAccountChargePaidBy.java | 4 +- .../SavingsAccountChargeRepository.java | 2 +- .../domain/SavingsAccountRepository.java | 14 ++-- .../domain/SavingsAccountTransaction.java | 24 +++--- .../SavingsAccountTransactionTaxDetails.java | 4 +- .../savings/domain/SavingsProduct.java | 14 ++-- ...WritePlatformServiceJpaRepositoryImpl.java | 20 ++--- ...WritePlatformServiceJpaRepositoryImpl.java | 33 +++++++-- ...WritePlatformServiceJpaRepositoryImpl.java | 20 +++-- ...WritePlatformServiceJpaRepositoryImpl.java | 21 ++++-- ...WritePlatformServiceJpaRepositoryImpl.java | 22 +++--- ...WritePlatformServiceJpaRepositoryImpl.java | 18 ++++- ...WritePlatformServiceJpaRepositoryImpl.java | 21 ++++-- .../account/domain/SelfBeneficiariesTPT.java | 4 +- .../shareaccounts/domain/ShareAccount.java | 4 +- .../domain/ShareAccountCharge.java | 14 +--- .../domain/ShareAccountChargePaidBy.java | 4 +- .../domain/ShareAccountDividendDetails.java | 4 +- .../domain/ShareAccountTransaction.java | 6 +- .../ShareAccountDataSerializer.java | 1 + ...WritePlatformServiceJpaRepositoryImpl.java | 39 ++++++---- .../shareproducts/domain/ShareProduct.java | 2 +- .../domain/ShareProductMarketPrice.java | 4 +- ...WritePlatformServiceJpaRepositoryImpl.java | 43 +++++++---- .../apache/fineract/spm/domain/Component.java | 4 +- .../fineract/spm/domain/LookupTable.java | 4 +- .../apache/fineract/spm/domain/Question.java | 6 +- .../apache/fineract/spm/domain/Response.java | 4 +- .../apache/fineract/spm/domain/Scorecard.java | 4 +- .../apache/fineract/spm/domain/Survey.java | 8 +- .../fineract/template/domain/Template.java | 18 ++--- .../template/domain/TemplateMapper.java | 4 +- .../useradministration/domain/AppUser.java | 8 +- .../domain/AppUserClientMapping.java | 4 +- .../domain/AppUserPreviousPassword.java | 4 +- .../domain/PasswordValidationPolicy.java | 7 +- .../PasswordValidationPolicyRepository.java | 2 +- .../useradministration/domain/Permission.java | 12 +-- .../useradministration/domain/Role.java | 6 +- .../domain/RoleRepository.java | 2 +- ...WritePlatformServiceJpaRepositoryImpl.java | 30 ++++++-- ...WritePlatformServiceJpaRepositoryImpl.java | 24 ++++-- .../main/resources/META-INF/persistence.xml | 14 ++-- .../META-INF/spring/infrastructure.xml | 7 +- 238 files changed, 1544 insertions(+), 913 deletions(-) create mode 100644 fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/AbstractPersistableCustom.java create mode 100644 fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/MySQLDictionaryCustom.java diff --git a/fineract-provider/build.gradle b/fineract-provider/build.gradle index 50e7e7a0f..b521d6c37 100644 --- a/fineract-provider/build.gradle +++ b/fineract-provider/build.gradle @@ -23,6 +23,7 @@ gradle clean tomcatrunwar buildscript { repositories { jcenter() + mavenCentral() } dependencies { @@ -30,6 +31,8 @@ buildscript { 'nl.javadude.gradle.plugins:license-gradle-plugin:0.11.0', 'org.zeroturnaround:gradle-jrebel-plugin:1.1.2', 'org.springframework.boot:spring-boot-gradle-plugin:1.1.6.RELEASE' // also change springDataJpaVersion below + classpath 'org.apache.openjpa:openjpa-all:2.4.1' + classpath 'at.schmutterer.oss.gradle:gradle-openjpa:0.2.0' } } @@ -42,6 +45,7 @@ apply plugin: 'idea' apply plugin: 'tomcat' apply plugin: 'project-report' apply plugin: 'java' +apply plugin: 'openjpa' /* define the valid syntax level for source files */ sourceCompatibility = JavaVersion.VERSION_1_8 @@ -64,9 +68,16 @@ repositories { jcenter() // mavenLocal() // useful for local dev using MariaDB4j SNAPSHOTs (not needed for real-world non-SNAPHOT builds) } +openjpa { + files = fileTree(sourceSets.main.output.classesDir).matching { + include '**/AbstractPersistableCustom.class' + include '**/domain/*.class' + + } + enforcePropertyRestrictions = true +} configurations { - hibernateDependencies providedRuntime // needed for Spring Boot executable WAR providedCompile compile() { @@ -136,11 +147,6 @@ task dist(type:Zip){ war { war.finalizedBy(bootRepackage) - if (project.hasProperty('buildType') && project.getProperty('buildType') == 'TEST') { - from(configurations.hibernateDependencies) { // notice the parens - into "WEB-INF/lib/" // no leading slash - } - } } license { @@ -200,7 +206,6 @@ sourceSets { integrationTest { compileClasspath += main.output + test.output runtimeClasspath += main.output + test.output - runtimeClasspath += configurations.hibernateDependencies } } @@ -231,9 +236,6 @@ configurations { } dependencies { driver 'org.drizzle.jdbc:drizzle-jdbc:1.3' - hibernateDependencies( - [group:'org.springframework.boot', name:'spring-boot-starter-data-jpa', version:'1.1.6.RELEASE'], - ) } test { diff --git a/fineract-provider/dependencies.gradle b/fineract-provider/dependencies.gradle index dcb27fe32..1623db72b 100644 --- a/fineract-provider/dependencies.gradle +++ b/fineract-provider/dependencies.gradle @@ -37,11 +37,13 @@ dependencies { [group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: springBootVersion], [group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: springBootVersion], [group: 'org.springframework.boot', name: 'spring-boot-starter-security', version: springBootVersion], - [group: 'org.eclipse.persistence', name: 'javax.persistence', version: '2.0.0'], + //[group: 'org.eclipse.persistence', name: 'javax.persistence', version: '2.0.0'], [group: 'org.springframework', name: 'spring-context-support', version: springVersion], [group: 'org.springframework.security.oauth', name: 'spring-security-oauth2', version: springOauthVersion], + [group: 'org.apache.openjpa', name:'openjpa-all', version:'2.4.1'], + [group: 'org.apache.openjpa', name:'openjpa-maven-plugin', version:'2.4.1'], [group: 'javax.ws.rs', name: 'jsr311-api', version: '1.1.1'], [group: 'com.sun.jersey', name: 'jersey-core', version: jerseyVersion], [group: 'com.sun.jersey', name: 'jersey-servlet', version: jerseyVersion], diff --git a/fineract-provider/dev-dependencies.gradle b/fineract-provider/dev-dependencies.gradle index 82e40313c..56fcb7779 100644 --- a/fineract-provider/dev-dependencies.gradle +++ b/fineract-provider/dev-dependencies.gradle @@ -37,10 +37,12 @@ dependencies { [group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: springBootVersion], [group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: springBootVersion], [group: 'org.springframework.boot', name: 'spring-boot-starter-security', version: springBootVersion], - [group: 'org.eclipse.persistence', name: 'javax.persistence', version: '2.0.0'], + //[group: 'org.eclipse.persistence', name: 'javax.persistence', version: '2.0.0'], [group: 'org.springframework', name: 'spring-context-support', version: springVersion], [group: 'org.springframework.security.oauth', name: 'spring-security-oauth2', version: springOauthVersion], + [group: 'org.apache.openjpa', name:'openjpa-all', version:'2.4.1'], + [group: 'org.apache.openjpa', name:'openjpa-maven-plugin', version:'2.4.1'], [group: 'javax.ws.rs', name: 'jsr311-api', version: '1.1.1'], [group: 'com.sun.jersey', name: 'jersey-core', version: jerseyVersion], [group: 'com.sun.jersey', name: 'jersey-servlet', version: jerseyVersion], diff --git a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/ProvisioningIntegrationTest.java b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/ProvisioningIntegrationTest.java index 107becef1..f07fdeea1 100644 --- a/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/ProvisioningIntegrationTest.java +++ b/fineract-provider/src/integrationTest/java/org/apache/fineract/integrationtests/common/ProvisioningIntegrationTest.java @@ -155,14 +155,24 @@ public class ProvisioningIntegrationTest { Assert.assertEquals(newdefintions.size(), requestedDefinitions.size()) ; for(int i = 0 ; i < newdefintions.size() ; i++) { Map requestedMap = (Map)requestedDefinitions.get(i) ; - Map newMap = (Map)newdefintions.get(i) ; - checkProperty("categoryId", requestedMap, newMap) ; - checkProperty("categoryName", requestedMap, newMap) ; - checkProperty("minAge", requestedMap, newMap) ; - checkProperty("maxAge", requestedMap, newMap) ; - checkProperty("provisioningPercentage", requestedMap, newMap) ; - checkProperty("liabilityAccount", requestedMap, newMap) ; - checkProperty("expenseAccount", requestedMap, newMap) ; + Object requestedCategoryId = requestedMap.get("categoryId") ; + boolean found = false ; + for(int j = 0 ; j < newdefintions.size(); j++) { + Map newMap = (Map)newdefintions.get(j) ; + Object newCategoryId = newMap.get("categoryId") ; + if(requestedCategoryId.equals(newCategoryId)) { + found = true ; + checkProperty("categoryId", requestedMap, newMap) ; + checkProperty("categoryName", requestedMap, newMap) ; + checkProperty("minAge", requestedMap, newMap) ; + checkProperty("maxAge", requestedMap, newMap) ; + checkProperty("provisioningPercentage", requestedMap, newMap) ; + checkProperty("liabilityAccount", requestedMap, newMap) ; + checkProperty("expenseAccount", requestedMap, newMap) ; + break ; //internal loop + } + } + if(!found) Assert.fail("No Category found with Id:"+requestedCategoryId); } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/closure/domain/GLClosureRepository.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/closure/domain/GLClosureRepository.java index cc4354758..75bfe7aba 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/accounting/closure/domain/GLClosureRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/closure/domain/GLClosureRepository.java @@ -25,6 +25,6 @@ import org.springframework.data.repository.query.Param; public interface GLClosureRepository extends JpaRepository, JpaSpecificationExecutor { - @Query("from GLClosure closure where closure.closingDate = (select max(closure1.closingDate) from GLClosure closure1 where closure1.office.id=:officeId) and closure.office.id= :officeId") + @Query("select closure from GLClosure closure where closure.closingDate = (select max(closure1.closingDate) from GLClosure closure1 where closure1.office.id=:officeId) and closure.office.id= :officeId") GLClosure getLatestGLClosureByBranch(@Param("officeId") Long officeId); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/domain/FinancialActivityAccount.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/domain/FinancialActivityAccount.java index 93f8e79de..3f87468bb 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/domain/FinancialActivityAccount.java +++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/domain/FinancialActivityAccount.java @@ -26,11 +26,11 @@ import javax.persistence.ManyToOne; import javax.persistence.Table; import org.apache.fineract.accounting.glaccount.domain.GLAccount; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "acc_gl_financial_activity_account") -public class FinancialActivityAccount extends AbstractPersistable { +public class FinancialActivityAccount extends AbstractPersistableCustom { @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "gl_account_id") diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/domain/FinancialActivityAccountRepository.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/domain/FinancialActivityAccountRepository.java index 741413380..940b57bda 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/domain/FinancialActivityAccountRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/domain/FinancialActivityAccountRepository.java @@ -26,7 +26,7 @@ import org.springframework.data.repository.query.Param; public interface FinancialActivityAccountRepository extends JpaRepository, JpaSpecificationExecutor { - @Query("from FinancialActivityAccount faa where faa.financialActivityType = :financialActivityType") + @Query("select faa from FinancialActivityAccount faa where faa.financialActivityType = :financialActivityType") FinancialActivityAccount findByFinancialActivityType(@Param("financialActivityType") int financialAccountType); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/service/FinancialActivityAccountWritePlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/service/FinancialActivityAccountWritePlatformServiceImpl.java index 558cc4116..c5e2e222c 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/service/FinancialActivityAccountWritePlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/financialactivityaccount/service/FinancialActivityAccountWritePlatformServiceImpl.java @@ -21,6 +21,9 @@ package org.apache.fineract.accounting.financialactivityaccount.service; import java.util.HashMap; import java.util.Map; +import javax.persistence.PersistenceException; + +import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.fineract.accounting.common.AccountingConstants.FINANCIAL_ACTIVITY; import org.apache.fineract.accounting.financialactivityaccount.api.FinancialActivityAccountsJsonInputParams; import org.apache.fineract.accounting.financialactivityaccount.domain.FinancialActivityAccount; @@ -76,7 +79,11 @@ public class FinancialActivityAccountWritePlatformServiceImpl implements Financi .withEntityId(financialActivityAccount.getId()) // .build(); } catch (DataIntegrityViolationException dataIntegrityViolationException) { - handleFinancialActivityAccountDataIntegrityIssues(command, dataIntegrityViolationException); + handleFinancialActivityAccountDataIntegrityIssues(command, dataIntegrityViolationException.getMostSpecificCause(), dataIntegrityViolationException); + return CommandProcessingResult.empty(); + }catch(final PersistenceException ee) { + Throwable throwable = ExceptionUtils.getRootCause(ee.getCause()) ; + handleFinancialActivityAccountDataIntegrityIssues(command, throwable, ee); return CommandProcessingResult.empty(); } } @@ -122,8 +129,12 @@ public class FinancialActivityAccountWritePlatformServiceImpl implements Financi .with(changes) // .build(); } catch (DataIntegrityViolationException dataIntegrityViolationException) { - handleFinancialActivityAccountDataIntegrityIssues(command, dataIntegrityViolationException); + handleFinancialActivityAccountDataIntegrityIssues(command, dataIntegrityViolationException.getMostSpecificCause(), dataIntegrityViolationException); return CommandProcessingResult.empty(); + }catch(final PersistenceException ee) { + Throwable throwable = ExceptionUtils.getRootCause(ee.getCause()) ; + handleFinancialActivityAccountDataIntegrityIssues(command, throwable, ee); + return CommandProcessingResult.empty(); } } @@ -138,8 +149,7 @@ public class FinancialActivityAccountWritePlatformServiceImpl implements Financi .build(); } - private void handleFinancialActivityAccountDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) { - final Throwable realCause = dve.getMostSpecificCause(); + private void handleFinancialActivityAccountDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dve) { if (realCause.getMessage().contains("financial_activity_type")) { final Integer financialActivityId = command .integerValueSansLocaleOfParameterNamed(FinancialActivityAccountsJsonInputParams.FINANCIAL_ACTIVITY_ID.getValue()); diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/domain/GLAccount.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/domain/GLAccount.java index 5ed1ab9ef..b68cd4a9c 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/domain/GLAccount.java +++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/glaccount/domain/GLAccount.java @@ -37,11 +37,11 @@ import org.apache.commons.lang.StringUtils; import org.apache.fineract.accounting.glaccount.api.GLAccountJsonInputParams; import org.apache.fineract.infrastructure.codes.domain.CodeValue; import org.apache.fineract.infrastructure.core.api.JsonCommand; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "acc_gl_account", uniqueConstraints = { @UniqueConstraint(columnNames = { "gl_code" }, name = "acc_gl_code") }) -public class GLAccount extends AbstractPersistable { +public class GLAccount extends AbstractPersistableCustom { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "parent_id") @@ -52,7 +52,7 @@ public class GLAccount extends AbstractPersistable { @OneToMany(fetch = FetchType.LAZY) @JoinColumn(name = "parent_id") - private final List children = new LinkedList<>(); + private List children = new LinkedList<>(); @Column(name = "name", nullable = false, length = 45) private String name; diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntryRepository.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntryRepository.java index 120b03e7f..c280f89da 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntryRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/domain/JournalEntryRepository.java @@ -29,24 +29,24 @@ import org.springframework.data.repository.query.Param; public interface JournalEntryRepository extends JpaRepository, JpaSpecificationExecutor, JournalEntryRepositoryCustom { - @Query("from JournalEntry journalEntry where journalEntry.transactionId= :transactionId and journalEntry.reversed is false and journalEntry.manualEntry is true") + @Query("select journalEntry from JournalEntry journalEntry where journalEntry.transactionId= :transactionId and journalEntry.reversed=false and journalEntry.manualEntry=true") List findUnReversedManualJournalEntriesByTransactionId(@Param("transactionId") String transactionId); @Query("select DISTINCT j.transactionId from JournalEntry j where j.transactionId not in (select DISTINCT je.transactionId from JournalEntry je where je.glAccount.id = :contraId)") List findNonContraTansactionIds(@Param("contraId") Long contraId); - @Query("select DISTINCT j.transactionId from JournalEntry j where j.office.id = :officeId and j.glAccount.id = :contraId and j.reversed is false and j.transactionId not in (select DISTINCT je.reversalJournalEntry.transactionId from JournalEntry je where je.reversed is true)") + @Query("select DISTINCT j.transactionId from JournalEntry j where j.office.id = :officeId and j.glAccount.id = :contraId and j.reversed=false and j.transactionId not in (select DISTINCT je.reversalJournalEntry.transactionId from JournalEntry je where je.reversed=true)") List findNonReversedContraTansactionIds(@Param("contraId") Long contraId, @Param("officeId") Long officeId); - @Query("from JournalEntry journalEntry where journalEntry.entityId= :entityId and journalEntry.entityType = :entityType") + @Query("select journalEntry from JournalEntry journalEntry where journalEntry.entityId= :entityId and journalEntry.entityType = :entityType") List findProvisioningJournalEntriesByEntityId(@Param("entityId") Long entityId, @Param("entityType") Integer entityType) ; - @Query("from JournalEntry journalEntry where journalEntry.transactionId= :transactionId and journalEntry.reversed is false and journalEntry.entityType = :entityType") + @Query("select journalEntry from JournalEntry journalEntry where journalEntry.transactionId= :transactionId and journalEntry.reversed=false and journalEntry.entityType = :entityType") List findJournalEntries(@Param("transactionId") String transactionId, @Param("entityType") Integer entityType); - @Query("from JournalEntry journalEntry where glAccount.id= :accountId and transactionId= :transactionId and transactionDate= :transactionDate" + /*@Query("select journalEntry from JournalEntry journalEntry where glAccount.id= :accountId and transactionId= :transactionId and transactionDate= :transactionDate" + " and type= :journalEntryType and entityType=1 and entityId= :loanId and loanTransaction.id= :loanTransactionId") JournalEntry findLOANJournalEntryWith(@Param("accountId") Long accountId, @Param("transactionId") String transactionId, @Param("transactionDate") Date transactionDate, @Param("journalEntryType") Integer journalEntryType, - @Param("loanId") Long loanId, @Param("loanTransactionId") Long loanTransactionId); + @Param("loanId") Long loanId, @Param("loanTransactionId") Long loanTransactionId);*/ } diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/domain/ProductToGLAccountMapping.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/domain/ProductToGLAccountMapping.java index 4c9bbaf93..78a5b4d07 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/domain/ProductToGLAccountMapping.java +++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/domain/ProductToGLAccountMapping.java @@ -20,41 +20,40 @@ package org.apache.fineract.accounting.producttoaccountmapping.domain; import javax.persistence.Column; import javax.persistence.Entity; -import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; import javax.persistence.UniqueConstraint; import org.apache.fineract.accounting.glaccount.domain.GLAccount; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.portfolio.charge.domain.Charge; import org.apache.fineract.portfolio.paymenttype.domain.PaymentType; -import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @Table(name = "acc_product_mapping", uniqueConstraints = { @UniqueConstraint(columnNames = { "product_id", "product_type", "financial_account_type", "payment_type" }, name = "financial_action") }) -public class ProductToGLAccountMapping extends AbstractPersistable { +public class ProductToGLAccountMapping extends AbstractPersistableCustom { - @ManyToOne(fetch = FetchType.LAZY) + @ManyToOne(optional=true) @JoinColumn(name = "gl_account_id") private GLAccount glAccount; - @Column(name = "product_id", nullable = false) + @Column(name = "product_id", nullable = true) private Long productId; - @ManyToOne(fetch = FetchType.LAZY) + @ManyToOne @JoinColumn(name = "payment_type", nullable = true) private PaymentType paymentType; - @ManyToOne(fetch = FetchType.LAZY) + @ManyToOne @JoinColumn(name = "charge_id", nullable = true) private Charge charge; - @Column(name = "product_type", nullable = false) + @Column(name = "product_type", nullable = true) private int productType; - @Column(name = "financial_account_type", nullable = false) + @Column(name = "financial_account_type", nullable = true) private int financialAccountType; public static ProductToGLAccountMapping createNew(final GLAccount glAccount, final Long productId, final int productType, diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/domain/ProductToGLAccountMappingRepository.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/domain/ProductToGLAccountMappingRepository.java index 230de00ad..0882c7baf 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/domain/ProductToGLAccountMappingRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/producttoaccountmapping/domain/ProductToGLAccountMappingRepository.java @@ -34,22 +34,22 @@ public interface ProductToGLAccountMappingRepository extends JpaRepository findAllPaymentTypeToFundSourceMappings(@Param("productId") Long productId, @Param("productType") int productType); /*** The financial Account Type for income from interest will always be 4 ***/ - @Query("from ProductToGLAccountMapping mapping where mapping.productId =:productId and mapping.productType =:productType and mapping.financialAccountType=4 and mapping.charge is not NULL") + @Query("select mapping from ProductToGLAccountMapping mapping where mapping.productId =:productId and mapping.productType =:productType and mapping.financialAccountType=4 and mapping.charge is not NULL") List findAllFeeToIncomeAccountMappings(@Param("productId") Long productId, @Param("productType") int productType); /*** The financial Account Type for income from interest will always be 5 ***/ - @Query("from ProductToGLAccountMapping mapping where mapping.productId =:productId and mapping.productType =:productType and mapping.financialAccountType=5 and mapping.charge is not NULL") + @Query("select mapping from ProductToGLAccountMapping mapping where mapping.productId =:productId and mapping.productType =:productType and mapping.financialAccountType=5 and mapping.charge is not NULL") List findAllPenaltyToIncomeAccountMappings(@Param("productId") Long productId, @Param("productType") int productType); diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/provisioning/domain/LoanProductProvisioningEntry.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/provisioning/domain/LoanProductProvisioningEntry.java index 49ea228fa..42db8d8e0 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/accounting/provisioning/domain/LoanProductProvisioningEntry.java +++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/provisioning/domain/LoanProductProvisioningEntry.java @@ -27,14 +27,14 @@ import javax.persistence.ManyToOne; import javax.persistence.Table; import org.apache.fineract.accounting.glaccount.domain.GLAccount; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.organisation.office.domain.Office; import org.apache.fineract.organisation.provisioning.domain.ProvisioningCategory; import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct; -import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @Table(name = "m_loanproduct_provisioning_entry") -public class LoanProductProvisioningEntry extends AbstractPersistable { +public class LoanProductProvisioningEntry extends AbstractPersistableCustom { @ManyToOne(optional = false) @JoinColumn(name = "history_id", referencedColumnName = "id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/provisioning/domain/ProvisioningEntry.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/provisioning/domain/ProvisioningEntry.java index 5b565079c..920c7c7f4 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/accounting/provisioning/domain/ProvisioningEntry.java +++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/provisioning/domain/ProvisioningEntry.java @@ -35,17 +35,17 @@ import javax.persistence.Temporal; import javax.persistence.TemporalType; import org.apache.fineract.useradministration.domain.AppUser; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_provisioning_history") -public class ProvisioningEntry extends AbstractPersistable { +public class ProvisioningEntry extends AbstractPersistableCustom { @Column(name = "journal_entry_created") private Boolean isJournalEntryCreated; @OneToMany(cascade = CascadeType.ALL, mappedBy = "entry", orphanRemoval = true, fetch=FetchType.EAGER) - Set provisioningEntries = new HashSet<>(); + private Set provisioningEntries = new HashSet<>(); @OneToOne @JoinColumn(name = "createdby_id") diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/provisioning/domain/ProvisioningEntryRepository.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/provisioning/domain/ProvisioningEntryRepository.java index 5abed2070..50c7ad2e4 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/accounting/provisioning/domain/ProvisioningEntryRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/provisioning/domain/ProvisioningEntryRepository.java @@ -27,9 +27,10 @@ import org.springframework.data.repository.query.Param; public interface ProvisioningEntryRepository extends JpaRepository, JpaSpecificationExecutor { - @Query("select entry from ProvisioningEntry entry where entry.createdDate = :createdDate") + //OPENJPA throws error if we use entry + @Query("select entry1 from ProvisioningEntry entry1 where entry1.createdDate = :createdDate") ProvisioningEntry findByProvisioningEntryDate(@Param("createdDate") Date createdDate); - @Query("select entry from ProvisioningEntry entry where entry.createdDate = (select max(entry1.createdDate) from ProvisioningEntry entry1 where entry1.isJournalEntryCreated='1')") + @Query("select entry1 from ProvisioningEntry entry1 where entry1.createdDate = (select max(entry2.createdDate) from ProvisioningEntry entry2 where entry2.isJournalEntryCreated=true)") ProvisioningEntry findExistingProvisioningEntryWithJournalEntries() ; } diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/rule/domain/AccountingRule.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/rule/domain/AccountingRule.java index a60372267..0b09b105e 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/accounting/rule/domain/AccountingRule.java +++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/rule/domain/AccountingRule.java @@ -41,11 +41,11 @@ import org.apache.fineract.accounting.journalentry.domain.JournalEntryType; import org.apache.fineract.accounting.rule.api.AccountingRuleJsonInputParams; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.organisation.office.domain.Office; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "acc_accounting_rule", uniqueConstraints = { @UniqueConstraint(columnNames = { "name" }, name = "accounting_rule_name_unique") }) -public class AccountingRule extends AbstractPersistable { +public class AccountingRule extends AbstractPersistableCustom { @Column(name = "name", nullable = false, length = 500) private String name; @@ -69,7 +69,7 @@ public class AccountingRule extends AbstractPersistable { private Boolean systemDefined; @OneToMany(cascade = CascadeType.ALL, mappedBy = "accountingRule", orphanRemoval = true, fetch=FetchType.EAGER) - private final List accountingTagRules = new ArrayList<>(); + private List accountingTagRules = new ArrayList<>(); @Column(name = "allow_multiple_credits", nullable = false) private boolean allowMultipleCreditEntries; diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/rule/domain/AccountingRuleRepository.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/rule/domain/AccountingRuleRepository.java index 89e67c22e..17d807c22 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/accounting/rule/domain/AccountingRuleRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/rule/domain/AccountingRuleRepository.java @@ -25,6 +25,6 @@ import org.springframework.data.repository.query.Param; public interface AccountingRuleRepository extends JpaRepository, JpaSpecificationExecutor { - @Query("from AccountingRule accountingRule where accountingRule.office is null or accountingRule.office.id =:officeId") + @Query("select accountingRule from AccountingRule accountingRule where accountingRule.office is null or accountingRule.office.id =:officeId") AccountingRule getAccountingRuleByOfficeId(@Param("officeId") Long officeId); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/rule/domain/AccountingTagRule.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/rule/domain/AccountingTagRule.java index f47e9778a..16f138dfb 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/accounting/rule/domain/AccountingTagRule.java +++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/rule/domain/AccountingTagRule.java @@ -27,11 +27,11 @@ import javax.persistence.UniqueConstraint; import org.apache.fineract.accounting.journalentry.domain.JournalEntryType; import org.apache.fineract.infrastructure.codes.domain.CodeValue; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "acc_rule_tags", uniqueConstraints = { @UniqueConstraint(columnNames = { "acc_rule_id", "tag_id", "acc_type_enum" }, name = "UNIQUE_ACCOUNT_RULE_TAGS") }) -public class AccountingTagRule extends AbstractPersistable { +public class AccountingTagRule extends AbstractPersistableCustom { @ManyToOne @JoinColumn(name = "acc_rule_id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/batch/exception/ErrorHandler.java b/fineract-provider/src/main/java/org/apache/fineract/batch/exception/ErrorHandler.java index 65d166d2a..76b373ca7 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/batch/exception/ErrorHandler.java +++ b/fineract-provider/src/main/java/org/apache/fineract/batch/exception/ErrorHandler.java @@ -31,6 +31,7 @@ import org.apache.fineract.infrastructure.core.exceptionmapper.PlatformResourceN import org.apache.fineract.infrastructure.core.exceptionmapper.UnsupportedParameterExceptionMapper; import org.apache.fineract.portfolio.loanaccount.exception.MultiDisbursementDataRequiredException; import org.apache.fineract.portfolio.loanproduct.exception.LinkedAccountRequiredException; +import org.springframework.dao.NonTransientDataAccessException; import org.springframework.transaction.TransactionException; import com.google.gson.Gson; @@ -120,6 +121,8 @@ public class ErrorHandler extends RuntimeException { final String errorBody = jsonHelper.toJson(mapper.toResponse((PlatformInternalServerException) exception).getEntity()); return new ErrorInfo(500, 5001, errorBody); + }else if(exception instanceof NonTransientDataAccessException) { + return new ErrorInfo(400, 4001, "{\"Exception\": " + exception.getMessage()+"}"); } return new ErrorInfo(500, 9999, "{\"Exception\": " + exception.toString() + "}"); diff --git a/fineract-provider/src/main/java/org/apache/fineract/batch/service/BatchApiServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/batch/service/BatchApiServiceImpl.java index d7aadd8aa..0eec7da47 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/batch/service/BatchApiServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/batch/service/BatchApiServiceImpl.java @@ -35,6 +35,7 @@ import org.apache.fineract.batch.exception.ErrorHandler; import org.apache.fineract.batch.exception.ErrorInfo; import org.apache.fineract.batch.service.ResolutionHelper.BatchRequestNode; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.NonTransientDataAccessException; import org.springframework.stereotype.Service; import org.springframework.transaction.TransactionException; import org.springframework.transaction.TransactionStatus; @@ -216,7 +217,22 @@ public class BatchApiServiceImpl implements BatchApiService { errResponseList.add(errResponse); return errResponseList; - } + }catch (final NonTransientDataAccessException ex) { + ErrorInfo e = ErrorHandler.handler(ex); + BatchResponse errResponse = new BatchResponse(); + errResponse.setStatusCode(e.getStatusCode()); + for (BatchResponse res : checkList) { + if (!res.getStatusCode().equals(200)) { + errResponse.setBody("Transaction is being rolled back. First erroneous request: \n" + new Gson().toJson(res)); + break; + } + } + checkList.clear(); + List errResponseList = new ArrayList<>(); + errResponseList.add(errResponse); + + return errResponseList; + } } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/commands/domain/CommandSource.java b/fineract-provider/src/main/java/org/apache/fineract/commands/domain/CommandSource.java index a859e8eed..a19d22c2b 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/commands/domain/CommandSource.java +++ b/fineract-provider/src/main/java/org/apache/fineract/commands/domain/CommandSource.java @@ -32,11 +32,11 @@ import org.apache.commons.lang.StringUtils; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.useradministration.domain.AppUser; import org.joda.time.DateTime; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_portfolio_command_source") -public class CommandSource extends AbstractPersistable { +public class CommandSource extends AbstractPersistableCustom { @Column(name = "action_name", nullable = true, length = 100) private String actionName; diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/accountnumberformat/domain/AccountNumberFormat.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/accountnumberformat/domain/AccountNumberFormat.java index 064c1a690..4ff34ccda 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/accountnumberformat/domain/AccountNumberFormat.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/accountnumberformat/domain/AccountNumberFormat.java @@ -25,16 +25,16 @@ import javax.persistence.UniqueConstraint; import org.apache.fineract.infrastructure.accountnumberformat.domain.AccountNumberFormatEnumerations.AccountNumberPrefixType; import org.apache.fineract.infrastructure.accountnumberformat.service.AccountNumberFormatConstants; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = AccountNumberFormatConstants.ACCOUNT_NUMBER_FORMAT_TABLE_NAME, uniqueConstraints = { @UniqueConstraint(columnNames = { AccountNumberFormatConstants.ACCOUNT_TYPE_ENUM_COLUMN_NAME }, name = AccountNumberFormatConstants.ACCOUNT_TYPE_UNIQUE_CONSTRAINT_NAME) }) -public class AccountNumberFormat extends AbstractPersistable { +public class AccountNumberFormat extends AbstractPersistableCustom { @Column(name = AccountNumberFormatConstants.ACCOUNT_TYPE_ENUM_COLUMN_NAME, nullable = false) private Integer accountTypeEnum; - @Column(name = AccountNumberFormatConstants.PREFIX_TYPE_ENUM_COLUMN_NAME, nullable = false) + @Column(name = AccountNumberFormatConstants.PREFIX_TYPE_ENUM_COLUMN_NAME, nullable = true) private Integer prefixEnum; protected AccountNumberFormat() { diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/accountnumberformat/domain/AccountNumberFormatRepository.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/accountnumberformat/domain/AccountNumberFormatRepository.java index 3557bad12..12396abe5 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/accountnumberformat/domain/AccountNumberFormatRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/accountnumberformat/domain/AccountNumberFormatRepository.java @@ -26,7 +26,7 @@ import org.springframework.data.repository.query.Param; public interface AccountNumberFormatRepository extends JpaRepository, JpaSpecificationExecutor { - public static final String FIND_ACCOUNT_NUMBER_FORMAT_FOR_ENTITY = "from AccountNumberFormat anf where anf.accountTypeEnum = :accountTypeEnum"; + public static final String FIND_ACCOUNT_NUMBER_FORMAT_FOR_ENTITY = "select anf from AccountNumberFormat anf where anf.accountTypeEnum = :accountTypeEnum"; @Query(FIND_ACCOUNT_NUMBER_FORMAT_FOR_ENTITY) AccountNumberFormat findOneByAccountTypeEnum(@Param("accountTypeEnum") Integer accountTypeEnum); diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/accountnumberformat/service/AccountNumberFormatWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/accountnumberformat/service/AccountNumberFormatWritePlatformServiceJpaRepositoryImpl.java index b4afef2e1..31fe1b2c0 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/accountnumberformat/service/AccountNumberFormatWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/accountnumberformat/service/AccountNumberFormatWritePlatformServiceJpaRepositoryImpl.java @@ -21,11 +21,14 @@ package org.apache.fineract.infrastructure.accountnumberformat.service; import java.util.LinkedHashMap; import java.util.Map; +import javax.persistence.PersistenceException; + +import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.fineract.infrastructure.accountnumberformat.data.AccountNumberFormatDataValidator; import org.apache.fineract.infrastructure.accountnumberformat.domain.AccountNumberFormat; +import org.apache.fineract.infrastructure.accountnumberformat.domain.AccountNumberFormatEnumerations.AccountNumberPrefixType; import org.apache.fineract.infrastructure.accountnumberformat.domain.AccountNumberFormatRepositoryWrapper; import org.apache.fineract.infrastructure.accountnumberformat.domain.EntityAccountType; -import org.apache.fineract.infrastructure.accountnumberformat.domain.AccountNumberFormatEnumerations.AccountNumberPrefixType; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder; @@ -74,8 +77,12 @@ public class AccountNumberFormatWritePlatformServiceJpaRepositoryImpl implements .withEntityId(accountNumberFormat.getId()) // .build(); } catch (final DataIntegrityViolationException dve) { - handleDataIntegrityIssues(command, dve); + handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch (final PersistenceException ee) { + Throwable throwable = ExceptionUtils.getRootCause(ee.getCause()) ; + handleDataIntegrityIssues(command, throwable, ee); + return CommandProcessingResult.empty(); } } @@ -110,8 +117,12 @@ public class AccountNumberFormatWritePlatformServiceJpaRepositoryImpl implements .with(actualChanges) // .build(); } catch (final DataIntegrityViolationException dve) { - handleDataIntegrityIssues(command, dve); + handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + } catch (final PersistenceException ee) { + Throwable throwable = ExceptionUtils.getRootCause(ee.getCause()) ; + handleDataIntegrityIssues(command, throwable, ee); + return CommandProcessingResult.empty(); } } @@ -126,13 +137,12 @@ public class AccountNumberFormatWritePlatformServiceJpaRepositoryImpl implements .build(); } + /* * Guaranteed to throw an exception no matter what the data integrity issue * is. */ - private void handleDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) { - - final Throwable realCause = dve.getMostSpecificCause(); + private void handleDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dve) { if (realCause.getMessage().contains(AccountNumberFormatConstants.ACCOUNT_TYPE_UNIQUE_CONSTRAINT_NAME)) { final Integer accountTypeId = command.integerValueSansLocaleOfParameterNamed(AccountNumberFormatConstants.accountTypeParamName); diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/cache/domain/PlatformCache.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/cache/domain/PlatformCache.java index 9af367bdd..9ccfa2d59 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/cache/domain/PlatformCache.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/cache/domain/PlatformCache.java @@ -22,11 +22,11 @@ import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Table; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "c_cache") -public class PlatformCache extends AbstractPersistable { +public class PlatformCache extends AbstractPersistableCustom { @Column(name = "cache_type_enum") private Integer cacheType; diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/codes/domain/Code.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/codes/domain/Code.java index 22042a30c..82fafb2a8 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/codes/domain/Code.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/codes/domain/Code.java @@ -33,17 +33,17 @@ import javax.persistence.UniqueConstraint; import org.apache.commons.lang.StringUtils; import org.apache.fineract.infrastructure.codes.exception.SystemDefinedCodeCannotBeChangedException; import org.apache.fineract.infrastructure.core.api.JsonCommand; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_code", uniqueConstraints = { @UniqueConstraint(columnNames = { "code_name" }, name = "code_name") }) -public class Code extends AbstractPersistable { +public class Code extends AbstractPersistableCustom { @Column(name = "code_name", length = 100) private String name; @Column(name = "is_system_defined") - private final boolean systemDefined; + private boolean systemDefined; @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "code", orphanRemoval = true) private Set values; diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/codes/domain/CodeValue.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/codes/domain/CodeValue.java index 5045c677e..8ee1ac848 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/codes/domain/CodeValue.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/codes/domain/CodeValue.java @@ -32,11 +32,11 @@ import org.apache.commons.lang.StringUtils; import org.apache.fineract.infrastructure.codes.CodeConstants.CODEVALUE_JSON_INPUT_PARAMS; import org.apache.fineract.infrastructure.codes.data.CodeValueData; import org.apache.fineract.infrastructure.core.api.JsonCommand; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_code_value", uniqueConstraints = { @UniqueConstraint(columnNames = { "code_id", "code_value" }, name = "code_value_duplicate") }) -public class CodeValue extends AbstractPersistable { +public class CodeValue extends AbstractPersistableCustom { @Column(name = "code_value", length = 100) private String label; diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/codes/service/CodeWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/codes/service/CodeWritePlatformServiceJpaRepositoryImpl.java index 3926d1857..672fc5e63 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/codes/service/CodeWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/codes/service/CodeWritePlatformServiceJpaRepositoryImpl.java @@ -20,6 +20,9 @@ package org.apache.fineract.infrastructure.codes.service; import java.util.Map; +import javax.persistence.PersistenceException; + +import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.fineract.infrastructure.codes.domain.Code; import org.apache.fineract.infrastructure.codes.domain.CodeRepository; import org.apache.fineract.infrastructure.codes.exception.CodeNotFoundException; @@ -70,8 +73,12 @@ public class CodeWritePlatformServiceJpaRepositoryImpl implements CodeWritePlatf return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(code.getId()).build(); } catch (final DataIntegrityViolationException dve) { - handleCodeDataIntegrityIssues(command, dve); + handleCodeDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch (final PersistenceException ee) { + Throwable throwable = ExceptionUtils.getRootCause(ee.getCause()) ; + handleCodeDataIntegrityIssues(command, throwable, ee); + return CommandProcessingResult.empty(); } } @@ -98,8 +105,12 @@ public class CodeWritePlatformServiceJpaRepositoryImpl implements CodeWritePlatf .with(changes) // .build(); } catch (final DataIntegrityViolationException dve) { - handleCodeDataIntegrityIssues(command, dve); - return null; + handleCodeDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); + return CommandProcessingResult.empty(); + }catch (final PersistenceException ee) { + Throwable throwable = ExceptionUtils.getRootCause(ee.getCause()) ; + handleCodeDataIntegrityIssues(command, throwable, ee); + return CommandProcessingResult.empty(); } } @@ -133,8 +144,7 @@ public class CodeWritePlatformServiceJpaRepositoryImpl implements CodeWritePlatf * Guaranteed to throw an exception no matter what the data integrity issue * is. */ - private void handleCodeDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) { - final Throwable realCause = dve.getMostSpecificCause(); + private void handleCodeDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dve) { if (realCause.getMessage().contains("code_name")) { final String name = command.stringValueOfParameterNamed("name"); throw new PlatformDataIntegrityException("error.msg.code.duplicate.name", "A code with name '" + name + "' already exists", diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ExternalService.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ExternalService.java index 5bbd0ed20..23008bed4 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ExternalService.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ExternalService.java @@ -23,11 +23,11 @@ import javax.persistence.Table; import javax.persistence.UniqueConstraint; import org.apache.fineract.infrastructure.core.api.JsonCommand; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "c_external_service", uniqueConstraints = { @UniqueConstraint(columnNames = { "name" }, name = "name_UNIQUE") }) -public class ExternalService extends AbstractPersistable { +public class ExternalService extends AbstractPersistableCustom { @Column(name = "name", length = 50) private String name; diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ExternalServicePropertiesPK.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ExternalServicePropertiesPK.java index c9fc33295..4e60badad 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ExternalServicePropertiesPK.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ExternalServicePropertiesPK.java @@ -23,6 +23,9 @@ import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Embeddable; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + @Embeddable public class ExternalServicePropertiesPK implements Serializable { @@ -48,5 +51,30 @@ public class ExternalServicePropertiesPK implements Serializable { public Long getExternalService() { return externalServiceId; } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (obj == this) { + return true; + } + if (obj.getClass() != getClass()) { + return false; + } + final ExternalServicePropertiesPK rhs = (ExternalServicePropertiesPK) obj; + return new EqualsBuilder() // + .append(this.externalServiceId, rhs.externalServiceId) // + .append(this.name, rhs.name) // + .isEquals(); + } + @Override + public int hashCode() { + return new HashCodeBuilder(17, 37) // + .append(this.externalServiceId) // + .append(this.name) // + .toHashCode(); + } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ExternalServicesProperties.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ExternalServicesProperties.java index 350405657..6e36b3dff 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ExternalServicesProperties.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ExternalServicesProperties.java @@ -52,7 +52,6 @@ public class ExternalServicesProperties { this.value = value; } - public static ExternalServicesProperties fromJson(final ExternalService externalService, final JsonCommand command) { final String name = command.stringValueOfParameterNamed(EXTERNALSERVICEPROPERTIES_JSON_INPUT_PARAMS.NAME.getValue()); final String value = command.stringValueOfParameterNamed(EXTERNALSERVICEPROPERTIES_JSON_INPUT_PARAMS.VALUE.getValue()); @@ -80,5 +79,4 @@ public class ExternalServicesProperties { public ExternalServicesPropertiesData toData() { return new ExternalServicesPropertiesData(this.externalServicePropertiesPK.getName(), this.value); } - } diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ExternalServicesPropertiesRepository.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ExternalServicesPropertiesRepository.java index 98a0e5cb0..6db62a383 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ExternalServicesPropertiesRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ExternalServicesPropertiesRepository.java @@ -20,9 +20,12 @@ package org.apache.fineract.infrastructure.configuration.domain; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; public interface ExternalServicesPropertiesRepository extends JpaRepository, JpaSpecificationExecutor { - ExternalServicesProperties findOneByExternalServicePropertiesPK(ExternalServicePropertiesPK externalServicesProptiesPK); + @Query("SELECT ep from ExternalServicesProperties ep where ep.externalServicePropertiesPK.name=:name and ep.externalServicePropertiesPK.externalServiceId=:externalServiceId") + ExternalServicesProperties findOneByExternalServicePropertiesPK(@Param("name") String name, @Param("externalServiceId") Long externalServiceId); } \ No newline at end of file diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ExternalServicesPropertiesRepositoryWrapper.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ExternalServicesPropertiesRepositoryWrapper.java index 92201f4db..76b038eef 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ExternalServicesPropertiesRepositoryWrapper.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/ExternalServicesPropertiesRepositoryWrapper.java @@ -34,7 +34,7 @@ public class ExternalServicesPropertiesRepositoryWrapper { public ExternalServicesProperties findOneByIdAndName(Long id, String name, String externalServiceName) { final ExternalServicesProperties externalServicesProperties = this.repository - .findOneByExternalServicePropertiesPK(new ExternalServicePropertiesPK(id, name)); + .findOneByExternalServicePropertiesPK(name,id); if (externalServicesProperties == null) throw new ExternalServiceConfigurationNotFoundException(externalServiceName, name); return externalServicesProperties; } diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/GlobalConfigurationProperty.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/GlobalConfigurationProperty.java index 40d681b4e..10f4e85be 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/GlobalConfigurationProperty.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/configuration/domain/GlobalConfigurationProperty.java @@ -30,14 +30,14 @@ import org.apache.fineract.infrastructure.configuration.data.GlobalConfiguration import org.apache.fineract.infrastructure.configuration.exception.GlobalConfigurationPropertyCannotBeModfied; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.security.exception.ForcePasswordResetException; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "c_configuration") -public class GlobalConfigurationProperty extends AbstractPersistable { +public class GlobalConfigurationProperty extends AbstractPersistableCustom { @Column(name = "name", nullable = false) - private final String name; + private String name; @Column(name = "enabled", nullable = false) private boolean enabled; @@ -49,7 +49,7 @@ public class GlobalConfigurationProperty extends AbstractPersistable { private Date dateValue; @Column(name = "description", nullable = true) - private final String description; + private String description; @Column(name = "is_trap_door", nullable = false) private boolean isTrapDoor; diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/data/ApiParameterError.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/data/ApiParameterError.java index 9a669a066..75a7ae0e2 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/data/ApiParameterError.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/data/ApiParameterError.java @@ -18,7 +18,9 @@ */ package org.apache.fineract.infrastructure.core.data; +import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Date; import java.util.List; public class ApiParameterError { @@ -57,6 +59,8 @@ public class ApiParameterError { */ private List args = new ArrayList<>(); + private final transient SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd"); + public static ApiParameterError generalError(final String globalisationMessageCode, final String defaultUserMessage, final Object... defaultUserMessageArgs) { return new ApiParameterError(globalisationMessageCode, defaultUserMessage, defaultUserMessageArgs); @@ -86,7 +90,12 @@ public class ApiParameterError { final List messageArgs = new ArrayList<>(); if (defaultUserMessageArgs != null) { for (final Object object : defaultUserMessageArgs) { - messageArgs.add(ApiErrorMessageArg.from(object)); + if(object instanceof Date){ + final String formattedDate = dateFormatter.format(object); + messageArgs.add(ApiErrorMessageArg.from(formattedDate)); + } else { + messageArgs.add(ApiErrorMessageArg.from(object)); + } } } this.args = messageArgs; diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/AbstractAuditableCustom.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/AbstractAuditableCustom.java index 4707af1e4..42ccf4e9a 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/AbstractAuditableCustom.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/AbstractAuditableCustom.java @@ -22,16 +22,17 @@ import java.io.Serializable; import java.util.Date; import javax.persistence.Column; +import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.MappedSuperclass; import javax.persistence.OneToOne; import javax.persistence.Temporal; import javax.persistence.TemporalType; +import org.apache.fineract.useradministration.domain.AppUser; import org.joda.time.DateTime; import org.springframework.data.domain.Auditable; import org.springframework.data.jpa.domain.AbstractAuditable; -import org.springframework.data.jpa.domain.AbstractPersistable; /** * A custom copy of {@link AbstractAuditable} to override the column names used @@ -46,21 +47,21 @@ import org.springframework.data.jpa.domain.AbstractPersistable; * the type of the auditing type's identifier */ @MappedSuperclass -public abstract class AbstractAuditableCustom extends AbstractPersistable implements Auditable { +public abstract class AbstractAuditableCustom extends AbstractPersistableCustom implements Auditable { private static final long serialVersionUID = 141481953116476081L; - @OneToOne + @OneToOne(fetch=FetchType.LAZY) @JoinColumn(name = "createdby_id") - private U createdBy; + private AppUser createdBy; @Column(name = "created_date") @Temporal(TemporalType.TIMESTAMP) private Date createdDate; - @OneToOne + @OneToOne(fetch=FetchType.LAZY) @JoinColumn(name = "lastmodifiedby_id") - private U lastModifiedBy; + private AppUser lastModifiedBy; @Column(name = "lastmodified_date") @Temporal(TemporalType.TIMESTAMP) @@ -72,7 +73,7 @@ public abstract class AbstractAuditableCustom extend * @see org.springframework.data.domain.Auditable#getCreatedBy() */ @Override - public U getCreatedBy() { + public AppUser getCreatedBy() { return this.createdBy; } @@ -84,7 +85,7 @@ public abstract class AbstractAuditableCustom extend * org.springframework.data.domain.Auditable#setCreatedBy(java.lang.Object) */ @Override - public void setCreatedBy(final U createdBy) { + public void setCreatedBy(final AppUser createdBy) { this.createdBy = createdBy; } @@ -119,7 +120,7 @@ public abstract class AbstractAuditableCustom extend * @see org.springframework.data.domain.Auditable#getLastModifiedBy() */ @Override - public U getLastModifiedBy() { + public AppUser getLastModifiedBy() { return this.lastModifiedBy; } @@ -132,7 +133,7 @@ public abstract class AbstractAuditableCustom extend * .Object) */ @Override - public void setLastModifiedBy(final U lastModifiedBy) { + public void setLastModifiedBy(final AppUser lastModifiedBy) { this.lastModifiedBy = lastModifiedBy; } diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/AbstractPersistableCustom.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/AbstractPersistableCustom.java new file mode 100644 index 000000000..a1ca55ac1 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/AbstractPersistableCustom.java @@ -0,0 +1,70 @@ +/** + * 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.domain; + +import java.io.Serializable; + +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.MappedSuperclass; + +import org.springframework.data.domain.Persistable; + + +@MappedSuperclass +public abstract class AbstractPersistableCustom implements Persistable { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + /* + * (non-Javadoc) + * + * @see org.springframework.data.domain.Persistable#getId() + */ + @Override + public Long getId() { + return id; + } + + /** + * Sets the id of the entity. + * + * @param id the id to set + */ + protected void setId(final Long id) { + + this.id = id; + } + + /* + * (non-Javadoc) + * + * @see org.springframework.data.domain.Persistable#isNew() + */ + @Override + public boolean isNew() { + + return null == this.id; + } + + //We have removed toString(), hashCode() and equals() methods. By adding them end up issues with OpenJPA +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/MySQLDictionaryCustom.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/MySQLDictionaryCustom.java new file mode 100644 index 000000000..24dc0ad85 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/domain/MySQLDictionaryCustom.java @@ -0,0 +1,46 @@ +/** + * 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.domain; + +import java.sql.Connection; +import java.sql.SQLException; + +import org.apache.openjpa.jdbc.sql.BooleanRepresentationFactory; +import org.apache.openjpa.jdbc.sql.MySQLDictionary; + +public class MySQLDictionaryCustom extends MySQLDictionary { + + public MySQLDictionaryCustom(){ + super(); + this.supportsSubselect = true; + this.booleanRepresentation = BooleanRepresentationFactory.BOOLEAN; + this.supportsGetGeneratedKeys = false ; + this.allowsAliasInBulkClause = true ; + this.useWildCardForCount = true ; + } + + @Override + public void connectedConfiguration(Connection conn) throws SQLException { + super.connectedConfiguration(conn); + this.supportsSubselect = true; + this.supportsGetGeneratedKeys = false ; + this.allowsAliasInBulkClause = true ; + this.useWildCardForCount = true ; + } +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/TomcatJdbcDataSourcePerTenantService.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/TomcatJdbcDataSourcePerTenantService.java index 34782a4f3..7f9be7199 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/TomcatJdbcDataSourcePerTenantService.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/service/TomcatJdbcDataSourcePerTenantService.java @@ -106,7 +106,8 @@ public class TomcatJdbcDataSourcePerTenantService implements RoutingDataSourceSe poolConfiguration.setRemoveAbandonedTimeout(tenantConnectionObj.getRemoveAbandonedTimeout()); poolConfiguration.setLogAbandoned(tenantConnectionObj.isLogAbandoned()); poolConfiguration.setAbandonWhenPercentageFull(tenantConnectionObj.getAbandonWhenPercentageFull()); - + poolConfiguration.setDefaultAutoCommit(true); + /** * Vishwas- Do we need to enable the below properties and add * ResetAbandonedTimer for long running batch Jobs? diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/domain/Report.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/domain/Report.java index 4d8fe0257..e39a59169 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/domain/Report.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/domain/Report.java @@ -40,13 +40,13 @@ import org.apache.fineract.infrastructure.core.data.ApiParameterError; import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder; import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException; import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import com.google.gson.JsonArray; @Entity @Table(name = "stretchy_report", uniqueConstraints = { @UniqueConstraint(columnNames = { "report_name" }, name = "unq_report_name") }) -public final class Report extends AbstractPersistable { +public final class Report extends AbstractPersistableCustom { @Column(name = "report_name", nullable = false, unique = true) private String reportName; @@ -74,7 +74,7 @@ public final class Report extends AbstractPersistable { private String reportSql; @OneToMany(cascade = CascadeType.ALL, mappedBy = "report", orphanRemoval = true, fetch=FetchType.EAGER) - private final Set reportParameterUsages = new HashSet<>(); + private Set reportParameterUsages = new HashSet<>(); public static Report fromJson(final JsonCommand command, final Collection reportTypes) { diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/domain/ReportParameter.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/domain/ReportParameter.java index 6d5ba2243..298e74096 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/domain/ReportParameter.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/domain/ReportParameter.java @@ -21,11 +21,11 @@ package org.apache.fineract.infrastructure.dataqueries.domain; import javax.persistence.Entity; import javax.persistence.Table; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "stretchy_parameter") -public class ReportParameter extends AbstractPersistable { +public class ReportParameter extends AbstractPersistableCustom { protected ReportParameter() { // diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/domain/ReportParameterUsage.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/domain/ReportParameterUsage.java index 43f674415..4d10fefdd 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/domain/ReportParameterUsage.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/domain/ReportParameterUsage.java @@ -24,13 +24,11 @@ import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "stretchy_report_parameter") -public final class ReportParameterUsage extends AbstractPersistable { +public final class ReportParameterUsage extends AbstractPersistableCustom { @ManyToOne(optional = false) @JoinColumn(name = "report_id", nullable = false) @@ -53,7 +51,7 @@ public final class ReportParameterUsage extends AbstractPersistable { this.reportParameterName = reportParameterName; } - @Override + /*@Override public boolean equals(final Object obj) { if (obj == null) { return false; } if (obj == this) { return true; } @@ -75,7 +73,7 @@ public final class ReportParameterUsage extends AbstractPersistable { .append(this.parameter.getId()) // .append(this.reportParameterName) // .toHashCode(); - } + }*/ public boolean hasIdOf(final Long id) { return getId().equals(id); diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java index a9b79a5ab..c40b94901 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/ReadWriteNonCoreDataServiceImpl.java @@ -28,10 +28,12 @@ import java.util.Locale; import java.util.Map; import java.util.Set; +import javax.persistence.PersistenceException; import javax.sql.DataSource; import org.apache.commons.lang.BooleanUtils; import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.fineract.infrastructure.codes.service.CodeReadPlatformService; import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService; import org.apache.fineract.infrastructure.core.api.JsonCommand; @@ -65,6 +67,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataAccessException; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.BadSqlGrammarException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.support.rowset.SqlRowSet; import org.springframework.jdbc.support.rowset.SqlRowSetMetaData; @@ -264,7 +267,18 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ // show duplicate datatable error msg if (realCause.getMessage() .contains("Duplicate entry") || cause.getMessage() - .contains("Duplicate entry")) { throw new PlatformDataIntegrityException("error.msg.datatable.registered", + .contains("Duplicate entry")) { + throw new PlatformDataIntegrityException("error.msg.datatable.registered", + "Datatable `" + dataTableName + "` is already registered against an application table.", "dataTableName", + dataTableName); } + logAsErrorUnexpectedDataIntegrityException(dve); + throw new PlatformDataIntegrityException("error.msg.unknown.data.integrity.issue", + "Unknown data integrity issue with resource."); + }catch (final PersistenceException dve) { + final Throwable cause = dve.getCause() ; + if (cause.getMessage() + .contains("Duplicate entry")) { + throw new PlatformDataIntegrityException("error.msg.datatable.registered", "Datatable `" + dataTableName + "` is already registered against an application table.", "dataTableName", dataTableName); } logAsErrorUnexpectedDataIntegrityException(dve); @@ -374,6 +388,19 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ logAsErrorUnexpectedDataIntegrityException(dve); throw new PlatformDataIntegrityException("error.msg.unknown.data.integrity.issue", "Unknown data integrity issue with resource."); + }catch(final PersistenceException e) { + final Throwable cause = e.getCause() ; + if (cause.getMessage() + .contains("Duplicate entry")) { + throw new PlatformDataIntegrityException( + "error.msg.datatable.entry.duplicate", "An entry already exists for datatable `" + dataTableName + + "` and application table with identifier `" + appTableId + "`.", + "dataTableName", dataTableName, appTableId); } + + logAsErrorUnexpectedDataIntegrityException(e); + throw new PlatformDataIntegrityException("error.msg.unknown.data.integrity.issue", + "Unknown data integrity issue with resource."); + } } @@ -405,6 +432,17 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ + "` and application table with identifier `" + appTableId + "`.", "dataTableName", dataTableName, appTableId); } + logAsErrorUnexpectedDataIntegrityException(dve); + throw new PlatformDataIntegrityException("error.msg.unknown.data.integrity.issue", + "Unknown data integrity issue with resource."); + }catch (final PersistenceException dve) { + final Throwable cause = dve.getCause() ; + if (cause.getMessage() + .contains("Duplicate entry")) { throw new PlatformDataIntegrityException( + "error.msg.datatable.entry.duplicate", "An entry already exists for datatable `" + dataTableName + + "` and application table with identifier `" + appTableId + "`.", + "dataTableName", dataTableName, appTableId); } + logAsErrorUnexpectedDataIntegrityException(dve); throw new PlatformDataIntegrityException("error.msg.unknown.data.integrity.issue", "Unknown data integrity issue with resource."); @@ -574,6 +612,21 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ } throwExceptionIfValidationWarningsExist(dataValidationErrors); + }catch (final PersistenceException | BadSqlGrammarException ee) { + Throwable realCause = ExceptionUtils.getRootCause(ee.getCause()) ; + final List dataValidationErrors = new ArrayList<>(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("datatable"); + if (realCause.getMessage().toLowerCase().contains("duplicate column name")) { + baseDataValidator.reset().parameter("name").failWithCode("duplicate.column.name"); + } else if (realCause.getMessage().contains("Table") && realCause.getMessage().contains("already exists")) { + baseDataValidator.reset().parameter("datatableName").value(datatableName).failWithCode("datatable.already.exists"); + } else if (realCause.getMessage().contains("Column") && realCause.getMessage().contains("big")) { + baseDataValidator.reset().parameter("column").failWithCode("length.too.big"); + } else if (realCause.getMessage().contains("Row") && realCause.getMessage().contains("large")) { + baseDataValidator.reset().parameter("row").failWithCode("size.too.large"); + } + + throwExceptionIfValidationWarningsExist(dataValidationErrors); } return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withResourceIdAsString(datatableName).build(); @@ -942,7 +995,22 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ } throwExceptionIfValidationWarningsExist(dataValidationErrors); - } + }catch (final PersistenceException ee) { + Throwable realCause = ExceptionUtils.getRootCause(ee.getCause()) ; + final List dataValidationErrors = new ArrayList<>(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("datatable"); + if (realCause.getMessage().toLowerCase().contains("duplicate column name")) { + baseDataValidator.reset().parameter("name").failWithCode("duplicate.column.name"); + } else if (realCause.getMessage().contains("Table") && realCause.getMessage().contains("already exists")) { + baseDataValidator.reset().parameter("datatableName").value(datatableName).failWithCode("datatable.already.exists"); + } else if (realCause.getMessage().contains("Column") && realCause.getMessage().contains("big")) { + baseDataValidator.reset().parameter("column").failWithCode("length.too.big"); + } else if (realCause.getMessage().contains("Row") && realCause.getMessage().contains("large")) { + baseDataValidator.reset().parameter("row").failWithCode("size.too.large"); + } + + throwExceptionIfValidationWarningsExist(dataValidationErrors); + } } @Transactional diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/ReportWritePlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/ReportWritePlatformServiceImpl.java index eb54824fc..25d3d181f 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/ReportWritePlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/dataqueries/service/ReportWritePlatformServiceImpl.java @@ -22,7 +22,10 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; +import javax.persistence.PersistenceException; + import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder; @@ -100,8 +103,12 @@ public class ReportWritePlatformServiceImpl implements ReportWritePlatformServic .withEntityId(report.getId()) // .build(); } catch (final DataIntegrityViolationException dve) { - handleReportDataIntegrityIssues(command, dve); + handleReportDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleReportDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -137,8 +144,12 @@ public class ReportWritePlatformServiceImpl implements ReportWritePlatformServic .with(changes) // .build(); } catch (final DataIntegrityViolationException dve) { - handleReportDataIntegrityIssues(command, dve); + handleReportDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleReportDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -169,10 +180,9 @@ public class ReportWritePlatformServiceImpl implements ReportWritePlatformServic * Guaranteed to throw an exception no matter what the data integrity issue * is. */ - private void handleReportDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) { + private void handleReportDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dve) { - final Throwable realCause = dve.getMostSpecificCause(); - if (realCause.getMessage().contains("unq_report_name")) { + if (realCause.getMessage().contains("unq_report_name") || realCause.getMessage().contains("report_name_UNIQUE")) { final String name = command.stringValueOfParameterNamed("reportName"); throw new PlatformDataIntegrityException("error.msg.report.duplicate.name", "A report with name '" + name + "' already exists", "name", name); diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/domain/Document.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/domain/Document.java index eb311b63f..5272252dc 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/domain/Document.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/domain/Document.java @@ -24,11 +24,11 @@ import javax.persistence.Table; import org.apache.commons.lang.StringUtils; import org.apache.fineract.infrastructure.documentmanagement.command.DocumentCommand; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_document") -public class Document extends AbstractPersistable { +public class Document extends AbstractPersistableCustom { @Column(name = "parent_entity_type", length = 50) private String parentEntityType; diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/domain/Image.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/domain/Image.java index c27a182ed..f3551428e 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/domain/Image.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/documentmanagement/domain/Image.java @@ -22,11 +22,11 @@ import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Table; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_image") -public final class Image extends AbstractPersistable { +public final class Image extends AbstractPersistableCustom { @Column(name = "location", length = 500) private String location; diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/entityaccess/domain/FineractEntityAccess.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/entityaccess/domain/FineractEntityAccess.java index 75c852a6e..93e87d9e6 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/entityaccess/domain/FineractEntityAccess.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/entityaccess/domain/FineractEntityAccess.java @@ -30,11 +30,11 @@ import javax.persistence.Table; import org.apache.fineract.infrastructure.codes.domain.CodeValue; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.entityaccess.FineractEntityAccessConstants; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_entity_to_entity_access") -public class FineractEntityAccess extends AbstractPersistable { +public class FineractEntityAccess extends AbstractPersistableCustom { @Column(name = "entity_type", length = 50) private String entityType; diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/entityaccess/domain/FineractEntityRelation.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/entityaccess/domain/FineractEntityRelation.java index b3d46c052..0ca00ffc6 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/entityaccess/domain/FineractEntityRelation.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/entityaccess/domain/FineractEntityRelation.java @@ -27,11 +27,11 @@ import javax.persistence.Entity; import javax.persistence.OneToMany; import javax.persistence.Table; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_entity_relation") -public class FineractEntityRelation extends AbstractPersistable { +public class FineractEntityRelation extends AbstractPersistableCustom { @OneToMany(cascade = CascadeType.ALL, mappedBy = "relationId", orphanRemoval = true) private Set fineractEntityToEntityMapping = new HashSet<>(); diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/entityaccess/domain/FineractEntityRelationRepository.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/entityaccess/domain/FineractEntityRelationRepository.java index 81e9da61d..ed409b173 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/entityaccess/domain/FineractEntityRelationRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/entityaccess/domain/FineractEntityRelationRepository.java @@ -24,6 +24,6 @@ import org.springframework.data.repository.query.Param; public interface FineractEntityRelationRepository extends JpaRepository{ - @Query("from FineractEntityRelation fea where fea.codeName= :codeName") + @Query("select fea from FineractEntityRelation fea where fea.codeName= :codeName") FineractEntityRelation findOneByCodeName(@Param("codeName") String codeName); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/entityaccess/domain/FineractEntityToEntityMapping.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/entityaccess/domain/FineractEntityToEntityMapping.java index 2ae9ef8bf..86f8e992f 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/entityaccess/domain/FineractEntityToEntityMapping.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/entityaccess/domain/FineractEntityToEntityMapping.java @@ -34,11 +34,11 @@ import javax.persistence.UniqueConstraint; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.entityaccess.api.FineractEntityApiResourceConstants; import org.apache.fineract.infrastructure.entityaccess.exception.FineractEntityToEntityMappingDateException; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_entity_to_entity_mapping", uniqueConstraints = { @UniqueConstraint(columnNames = { "rel_id", "from_id", "to_id" }) }) -public class FineractEntityToEntityMapping extends AbstractPersistable { +public class FineractEntityToEntityMapping extends AbstractPersistableCustom { @ManyToOne @JoinColumn(name = "rel_id") @@ -50,11 +50,11 @@ public class FineractEntityToEntityMapping extends AbstractPersistable { @Column(name = "to_id") private Long toId; - @Column(name = "start_date", nullable = false) + @Column(name = "start_date", nullable = true) @Temporal(TemporalType.DATE) private Date startDate; - @Column(name = "end_date", nullable = false) + @Column(name = "end_date", nullable = true) @Temporal(TemporalType.DATE) private Date endDate; diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/entityaccess/domain/FineractEntityToEntityMappingRepository.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/entityaccess/domain/FineractEntityToEntityMappingRepository.java index 5ec3293fc..b67f6e16e 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/entityaccess/domain/FineractEntityToEntityMappingRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/entityaccess/domain/FineractEntityToEntityMappingRepository.java @@ -27,6 +27,6 @@ public interface FineractEntityToEntityMappingRepository extends JpaRepository { +public class HookConfiguration extends AbstractPersistableCustom { @ManyToOne(optional = false) @JoinColumn(name = "hook_id", referencedColumnName = "id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/domain/HookRepository.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/domain/HookRepository.java index 95011421e..123b194c6 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/domain/HookRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/domain/HookRepository.java @@ -28,12 +28,12 @@ import org.springframework.data.repository.query.Param; public interface HookRepository extends JpaRepository, JpaSpecificationExecutor { - @Query("select hook from Hook hook inner join hook.events event where event.entityName = :entityName and event.actionName = :actionName and hook.isActive = 1") + @Query("select hook from Hook hook inner join hook.events event where event.entityName = :entityName and event.actionName = :actionName and hook.isActive = true") List findAllHooksListeningToEvent( @Param("entityName") String entityName, @Param("actionName") String actionName); - @Query("from Hook hook where hook.template.id = :templateId ") + @Query("select hook from Hook hook where hook.template.id = :templateId ") Hook findOneByTemplateId(@Param("templateId") Long templateId); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/domain/HookResource.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/domain/HookResource.java index 9b6b2f609..161dbe610 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/domain/HookResource.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/domain/HookResource.java @@ -24,11 +24,11 @@ import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_hook_registered_events") -public class HookResource extends AbstractPersistable { +public class HookResource extends AbstractPersistableCustom { @ManyToOne(optional = false) @JoinColumn(name = "hook_id", referencedColumnName = "id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/domain/HookTemplate.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/domain/HookTemplate.java index 904db7aa3..9294ad254 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/domain/HookTemplate.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/domain/HookTemplate.java @@ -32,17 +32,17 @@ import javax.persistence.Table; import org.apache.commons.lang.StringUtils; import org.apache.fineract.infrastructure.core.api.JsonCommand; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_hook_templates") -public class HookTemplate extends AbstractPersistable { +public class HookTemplate extends AbstractPersistableCustom { @Column(name = "name", nullable = false, length = 100) private String name; @OneToMany(cascade = CascadeType.ALL, mappedBy = "template", orphanRemoval = true, fetch=FetchType.EAGER) - private final Set fields = new HashSet<>(); + private Set fields = new HashSet<>(); private HookTemplate(final String name) { diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/domain/HookTemplateRepository.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/domain/HookTemplateRepository.java index 2902b40dc..c0e53a700 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/domain/HookTemplateRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/domain/HookTemplateRepository.java @@ -27,6 +27,6 @@ public interface HookTemplateRepository extends JpaRepository, JpaSpecificationExecutor { - @Query("from HookTemplate template where template.name = :name") + @Query("select template from HookTemplate template where template.name = :name") HookTemplate findOne(@Param("name") String name); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/domain/Schema.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/domain/Schema.java index 728e2920e..223abe59e 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/domain/Schema.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/domain/Schema.java @@ -24,11 +24,11 @@ import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_hook_schema") -public class Schema extends AbstractPersistable { +public class Schema extends AbstractPersistableCustom { @ManyToOne(optional = false) @JoinColumn(name = "hook_template_id", referencedColumnName = "id", nullable = false) @@ -44,7 +44,7 @@ public class Schema extends AbstractPersistable { private String placeholder; @Column(name = "optional", nullable = false) - private final boolean optional = false; + private boolean optional = false; public Schema() { // diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/service/HookWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/service/HookWritePlatformServiceJpaRepositoryImpl.java index 16965129d..d7e682eed 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/service/HookWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/hooks/service/HookWritePlatformServiceJpaRepositoryImpl.java @@ -18,9 +18,26 @@ */ package org.apache.fineract.infrastructure.hooks.service; -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; +import static org.apache.fineract.infrastructure.hooks.api.HookApiConstants.actionNameParamName; +import static org.apache.fineract.infrastructure.hooks.api.HookApiConstants.configParamName; +import static org.apache.fineract.infrastructure.hooks.api.HookApiConstants.contentTypeName; +import static org.apache.fineract.infrastructure.hooks.api.HookApiConstants.entityNameParamName; +import static org.apache.fineract.infrastructure.hooks.api.HookApiConstants.eventsParamName; +import static org.apache.fineract.infrastructure.hooks.api.HookApiConstants.nameParamName; +import static org.apache.fineract.infrastructure.hooks.api.HookApiConstants.payloadURLName; +import static org.apache.fineract.infrastructure.hooks.api.HookApiConstants.templateIdParamName; +import static org.apache.fineract.infrastructure.hooks.api.HookApiConstants.webTemplateName; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import javax.persistence.PersistenceException; + +import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.ApiParameterError; import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; @@ -29,7 +46,13 @@ import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder; import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException; import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException; import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper; -import org.apache.fineract.infrastructure.hooks.domain.*; +import org.apache.fineract.infrastructure.hooks.domain.Hook; +import org.apache.fineract.infrastructure.hooks.domain.HookConfiguration; +import org.apache.fineract.infrastructure.hooks.domain.HookRepository; +import org.apache.fineract.infrastructure.hooks.domain.HookResource; +import org.apache.fineract.infrastructure.hooks.domain.HookTemplate; +import org.apache.fineract.infrastructure.hooks.domain.HookTemplateRepository; +import org.apache.fineract.infrastructure.hooks.domain.Schema; import org.apache.fineract.infrastructure.hooks.exception.HookNotFoundException; import org.apache.fineract.infrastructure.hooks.exception.HookTemplateNotFoundException; import org.apache.fineract.infrastructure.hooks.processor.ProcessorHelper; @@ -44,13 +67,12 @@ import org.springframework.cache.annotation.CacheEvict; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; + import retrofit.RetrofitError; -import java.util.*; -import java.util.Map.Entry; - -import static org.apache.fineract.infrastructure.hooks.api.HookApiConstants.*; - @Service public class HookWritePlatformServiceJpaRepositoryImpl implements @@ -117,8 +139,12 @@ public class HookWritePlatformServiceJpaRepositoryImpl .withCommandId(command.commandId()) .withEntityId(hook.getId()).build(); } catch (final DataIntegrityViolationException dve) { - handleHookDataIntegrityIssues(command, dve); + handleHookDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleHookDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -181,8 +207,12 @@ public class HookWritePlatformServiceJpaRepositoryImpl .with(changes) // .build(); } catch (final DataIntegrityViolationException dve) { - handleHookDataIntegrityIssues(command, dve); - return null; + handleHookDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); + return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleHookDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -192,12 +222,9 @@ public class HookWritePlatformServiceJpaRepositoryImpl public CommandProcessingResult deleteHook(final Long hookId) { this.context.authenticatedUser(); - final Hook hook = retrieveHookBy(hookId); - try { this.hookRepository.delete(hook); - this.hookRepository.flush(); } catch (final DataIntegrityViolationException e) { throw new PlatformDataIntegrityException( "error.msg.unknown.data.integrity.issue", @@ -348,9 +375,8 @@ public class HookWritePlatformServiceJpaRepositoryImpl } } - private void handleHookDataIntegrityIssues(final JsonCommand command, - final DataIntegrityViolationException dve) { - final Throwable realCause = dve.getMostSpecificCause(); + private void handleHookDataIntegrityIssues(final JsonCommand command, final Throwable realCause, + final Exception dve) { if (realCause.getMessage().contains("hook_name")) { final String name = command.stringValueOfParameterNamed("name"); throw new PlatformDataIntegrityException( diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/domain/ScheduledJobDetail.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/domain/ScheduledJobDetail.java index 659c3dbf8..752f3d0ce 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/domain/ScheduledJobDetail.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/domain/ScheduledJobDetail.java @@ -31,11 +31,11 @@ import javax.persistence.TemporalType; import org.apache.commons.lang.StringUtils; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.jobs.api.SchedulerJobApiConstants; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "job") -public class ScheduledJobDetail extends AbstractPersistable { +public class ScheduledJobDetail extends AbstractPersistableCustom { @Column(name = "name") private String jobName; diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/domain/ScheduledJobDetailRepository.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/domain/ScheduledJobDetailRepository.java index 86140a20c..d786748d4 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/domain/ScheduledJobDetailRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/domain/ScheduledJobDetailRepository.java @@ -28,14 +28,14 @@ import org.springframework.data.repository.query.Param; public interface ScheduledJobDetailRepository extends JpaRepository, JpaSpecificationExecutor { - @Query("from ScheduledJobDetail jobDetail where jobDetail.jobKey = :jobKey") + @Query("select jobDetail from ScheduledJobDetail jobDetail where jobDetail.jobKey = :jobKey") ScheduledJobDetail findByJobKey(@Param("jobKey") String jobKey); - @Query("from ScheduledJobDetail jobDetail where jobDetail.id=:jobId") + @Query("select jobDetail from ScheduledJobDetail jobDetail where jobDetail.id=:jobId") ScheduledJobDetail findByJobId(@Param("jobId") Long jobId); @Lock(value = LockModeType.PESSIMISTIC_WRITE) - @Query("from ScheduledJobDetail jobDetail where jobDetail.jobKey = :jobKey") + @Query("select jobDetail from ScheduledJobDetail jobDetail where jobDetail.jobKey = :jobKey") ScheduledJobDetail findByJobKeyWithLock(@Param("jobKey") String jobKey); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/domain/ScheduledJobRunHistory.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/domain/ScheduledJobRunHistory.java index 8c6600201..c60fe48aa 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/domain/ScheduledJobRunHistory.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/domain/ScheduledJobRunHistory.java @@ -28,11 +28,11 @@ import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "job_run_history") -public class ScheduledJobRunHistory extends AbstractPersistable { +public class ScheduledJobRunHistory extends AbstractPersistableCustom { @ManyToOne @JoinColumn(name = "job_id") diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/domain/SchedulerDetail.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/domain/SchedulerDetail.java index 0afb31b78..675e8f918 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/domain/SchedulerDetail.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/domain/SchedulerDetail.java @@ -22,11 +22,11 @@ import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Table; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "scheduler_detail") -public class SchedulerDetail extends AbstractPersistable { +public class SchedulerDetail extends AbstractPersistableCustom { @Column(name = "execute_misfired_jobs") private boolean executeInstructionForMisfiredJobs; diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/reportmailingjob/domain/ReportMailingJobConfiguration.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/reportmailingjob/domain/ReportMailingJobConfiguration.java index 17eb7b68c..b14c8331b 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/reportmailingjob/domain/ReportMailingJobConfiguration.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/reportmailingjob/domain/ReportMailingJobConfiguration.java @@ -23,11 +23,11 @@ import javax.persistence.Entity; import javax.persistence.Table; import javax.persistence.UniqueConstraint; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_report_mailing_job_configuration", uniqueConstraints = { @UniqueConstraint(columnNames = { "name" }, name = "unique_name") }) -public class ReportMailingJobConfiguration extends AbstractPersistable { +public class ReportMailingJobConfiguration extends AbstractPersistableCustom { private static final long serialVersionUID = 3099279770861263184L; @Column(name = "name", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/reportmailingjob/domain/ReportMailingJobRunHistory.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/reportmailingjob/domain/ReportMailingJobRunHistory.java index 4839ed637..99d1ef927 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/reportmailingjob/domain/ReportMailingJobRunHistory.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/reportmailingjob/domain/ReportMailingJobRunHistory.java @@ -28,12 +28,12 @@ import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.joda.time.DateTime; -import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @Table(name = "m_report_mailing_job_run_history") -public class ReportMailingJobRunHistory extends AbstractPersistable { +public class ReportMailingJobRunHistory extends AbstractPersistableCustom { private static final long serialVersionUID = -3757370929988421076L; @ManyToOne diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/sms/domain/SmsMessage.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/sms/domain/SmsMessage.java index 003f086bb..377834aa9 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/sms/domain/SmsMessage.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/sms/domain/SmsMessage.java @@ -33,11 +33,11 @@ import org.apache.fineract.infrastructure.sms.SmsApiConstants; import org.apache.fineract.organisation.staff.domain.Staff; import org.apache.fineract.portfolio.client.domain.Client; import org.apache.fineract.portfolio.group.domain.Group; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "sms_messages_outbound") -public class SmsMessage extends AbstractPersistable { +public class SmsMessage extends AbstractPersistableCustom { @ManyToOne @JoinColumn(name = "group_id", nullable = true) diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/survey/domain/Likelihood.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/survey/domain/Likelihood.java index 60f2481c0..914451dbf 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/survey/domain/Likelihood.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/survey/domain/Likelihood.java @@ -28,11 +28,11 @@ import javax.persistence.Table; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.survey.api.LikelihoodApiConstants; import org.apache.fineract.infrastructure.survey.data.LikelihoodStatus; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "ppi_likelihoods_ppi") -public final class Likelihood extends AbstractPersistable { +public final class Likelihood extends AbstractPersistableCustom { @Column(name = "ppi_name", nullable = false) private String ppiName; diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/survey/domain/LikelihoodRepository.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/survey/domain/LikelihoodRepository.java index dc4975309..681c3eb57 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/survey/domain/LikelihoodRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/survey/domain/LikelihoodRepository.java @@ -29,7 +29,7 @@ import java.util.List; public interface LikelihoodRepository extends JpaRepository, JpaSpecificationExecutor { - @Query("FROM Likelihood WHERE ppi_name =:ppiName AND id !=:id") + @Query("select liklihood FROM Likelihood liklihood WHERE ppi_name =:ppiName AND id <>:id") List findByPpiNameAndLikeliHoodId(@Param("ppiName") String ppiName,@Param("id") Long likeliHoodId); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/mix/domain/MixTaxonomyMapping.java b/fineract-provider/src/main/java/org/apache/fineract/mix/domain/MixTaxonomyMapping.java index 6573f935d..3215bccf3 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/mix/domain/MixTaxonomyMapping.java +++ b/fineract-provider/src/main/java/org/apache/fineract/mix/domain/MixTaxonomyMapping.java @@ -24,11 +24,11 @@ import javax.persistence.Table; import org.apache.commons.lang.StringUtils; import org.apache.fineract.infrastructure.core.api.JsonCommand; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "mix_taxonomy_mapping") -public class MixTaxonomyMapping extends AbstractPersistable { +public class MixTaxonomyMapping extends AbstractPersistableCustom { @Column(name = "identifier") private String identifier; diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/holiday/domain/Holiday.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/holiday/domain/Holiday.java index e506a5891..be79b256a 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/holiday/domain/Holiday.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/holiday/domain/Holiday.java @@ -54,13 +54,13 @@ import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidati import org.apache.fineract.organisation.holiday.api.HolidayApiConstants; import org.apache.fineract.organisation.office.domain.Office; import org.joda.time.LocalDate; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import com.google.gson.JsonArray; @Entity @Table(name = "m_holiday", uniqueConstraints = { @UniqueConstraint(columnNames = { "name" }, name = "holiday_name") }) -public class Holiday extends AbstractPersistable { +public class Holiday extends AbstractPersistableCustom { @Column(name = "name", unique = true, nullable = false, length = 100) private String name; diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/holiday/domain/HolidayRepository.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/holiday/domain/HolidayRepository.java index 9be986eb9..f7e4e1985 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/holiday/domain/HolidayRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/holiday/domain/HolidayRepository.java @@ -32,6 +32,6 @@ public interface HolidayRepository extends JpaRepository, JpaSpec List findByOfficeIdAndGreaterThanDate(@Param("officeId") Long officeId, @Param("date") Date date, @Param("status") Integer status); - @Query("from Holiday holiday where holiday.processed = false and holiday.status = :status") + @Query("select holiday from Holiday holiday where holiday.processed = false and holiday.status = :status") List findUnprocessed(@Param("status") Integer status); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/holiday/service/HolidayWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/holiday/service/HolidayWritePlatformServiceJpaRepositoryImpl.java index 04cf4dfd5..6bce676d1 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/holiday/service/HolidayWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/holiday/service/HolidayWritePlatformServiceJpaRepositoryImpl.java @@ -24,6 +24,9 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; +import javax.persistence.PersistenceException; + +import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder; @@ -94,8 +97,12 @@ public class HolidayWritePlatformServiceJpaRepositoryImpl implements HolidayWrit return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(holiday.getId()).build(); } catch (final DataIntegrityViolationException dve) { - handleDataIntegrityIssues(command, dve); + handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -124,8 +131,12 @@ public class HolidayWritePlatformServiceJpaRepositoryImpl implements HolidayWrit return new CommandProcessingResultBuilder().withEntityId(holiday.getId()).with(changes).build(); } catch (final DataIntegrityViolationException dve) { - handleDataIntegrityIssues(command, dve); + handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -168,8 +179,7 @@ public class HolidayWritePlatformServiceJpaRepositoryImpl implements HolidayWrit return offices; } - private void handleDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) { - final Throwable realCause = dve.getMostSpecificCause(); + private void handleDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dve) { if (realCause.getMessage().contains("holiday_name")) { final String name = command.stringValueOfParameterNamed("name"); throw new PlatformDataIntegrityException("error.msg.holiday.duplicate.name", "Holiday with name `" + name + "` already exists", diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/domain/ApplicationCurrency.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/domain/ApplicationCurrency.java index 911a4f959..352c85a6a 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/domain/ApplicationCurrency.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/domain/ApplicationCurrency.java @@ -24,29 +24,29 @@ import javax.persistence.Table; import org.apache.fineract.organisation.monetary.data.CurrencyData; import org.apache.fineract.organisation.office.domain.OrganisationCurrency; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_currency") -public class ApplicationCurrency extends AbstractPersistable { +public class ApplicationCurrency extends AbstractPersistableCustom { @Column(name = "code", nullable = false, length = 3) - private final String code; + private String code; @Column(name = "decimal_places", nullable = false) - private final Integer decimalPlaces; + private Integer decimalPlaces; @Column(name = "currency_multiplesof") - private final Integer inMultiplesOf; + private Integer inMultiplesOf; @Column(name = "name", nullable = false, length = 50) - private final String name; + private String name; @Column(name = "internationalized_name_code", nullable = false, length = 50) - private final String nameCode; + private String nameCode; @Column(name = "display_symbol", nullable = true, length = 10) - private final String displaySymbol; + private String displaySymbol; protected ApplicationCurrency() { this.code = null; diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/domain/MonetaryCurrency.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/domain/MonetaryCurrency.java index 641567b4b..d91ebc47b 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/domain/MonetaryCurrency.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/domain/MonetaryCurrency.java @@ -25,13 +25,13 @@ import javax.persistence.Embeddable; public class MonetaryCurrency { @Column(name = "currency_code", length = 3, nullable = false) - private final String code; + private String code; @Column(name = "currency_digits", nullable = false) - private final int digitsAfterDecimal; + private int digitsAfterDecimal; @Column(name = "currency_multiplesof") - private final Integer inMultiplesOf; + private Integer inMultiplesOf; protected MonetaryCurrency() { this.code = null; diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/domain/Money.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/domain/Money.java index d8960f491..8ffdb187e 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/domain/Money.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/monetary/domain/Money.java @@ -29,16 +29,16 @@ import javax.persistence.Embeddable; public class Money implements Comparable { @Column(name = "currency_code", length = 3) - private final String currencyCode; + private String currencyCode; @Column(name = "currency_digits") - private final int currencyDigitsAfterDecimal; + private int currencyDigitsAfterDecimal; @Column(name = "currency_multiplesof") - private final Integer inMultiplesOf; + private Integer inMultiplesOf; @Column(name = "amount", scale = 6, precision = 19) - private final BigDecimal amount; + private BigDecimal amount; public static Money total(final Money... monies) { if (monies.length == 0) { throw new IllegalArgumentException("Money array must not be empty"); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/office/domain/Office.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/office/domain/Office.java index dadf6d74c..c64e856ce 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/office/domain/Office.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/office/domain/Office.java @@ -37,19 +37,19 @@ import javax.persistence.UniqueConstraint; import org.apache.commons.lang.StringUtils; import org.apache.fineract.infrastructure.core.api.JsonCommand; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.organisation.office.exception.CannotUpdateOfficeWithParentOfficeSameAsSelf; import org.apache.fineract.organisation.office.exception.RootOfficeParentCannotBeUpdated; import org.joda.time.LocalDate; -import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @Table(name = "m_office", uniqueConstraints = { @UniqueConstraint(columnNames = { "name" }, name = "name_org"), @UniqueConstraint(columnNames = { "external_id" }, name = "externalid_org") }) -public class Office extends AbstractPersistable { +public class Office extends AbstractPersistableCustom { @OneToMany(fetch = FetchType.LAZY) @JoinColumn(name = "parent_id") - private final List children = new LinkedList<>(); + private List children = new LinkedList<>(); @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "parent_id") diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/office/domain/OfficeTransaction.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/office/domain/OfficeTransaction.java index d08ba1fb2..986c364a0 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/office/domain/OfficeTransaction.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/office/domain/OfficeTransaction.java @@ -35,11 +35,11 @@ import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency; import org.apache.fineract.organisation.monetary.domain.Money; import org.joda.time.LocalDate; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_office_transaction") -public class OfficeTransaction extends AbstractPersistable { +public class OfficeTransaction extends AbstractPersistableCustom { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "from_office_id") diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/office/domain/OrganisationCurrency.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/office/domain/OrganisationCurrency.java index 894628a2b..43263efa7 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/office/domain/OrganisationCurrency.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/office/domain/OrganisationCurrency.java @@ -23,32 +23,32 @@ import javax.persistence.Entity; import javax.persistence.Table; import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; /** * Represents currencies allowed for this MFI/organisation. */ @Entity @Table(name = "m_organisation_currency") -public class OrganisationCurrency extends AbstractPersistable { +public class OrganisationCurrency extends AbstractPersistableCustom { @Column(name = "code", nullable = false, length = 3) - private final String code; + private String code; @Column(name = "decimal_places", nullable = false) - private final Integer decimalPlaces; + private Integer decimalPlaces; @Column(name = "currency_multiplesof") - private final Integer inMultiplesOf; + private Integer inMultiplesOf; @Column(name = "name", nullable = false, length = 50) - private final String name; + private String name; @Column(name = "internationalized_name_code", nullable = false, length = 50) - private final String nameCode; + private String nameCode; @Column(name = "display_symbol", nullable = true, length = 10) - private final String displaySymbol; + private String displaySymbol; protected OrganisationCurrency() { this.code = null; diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/office/service/OfficeWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/office/service/OfficeWritePlatformServiceJpaRepositoryImpl.java index 1377e473b..ba12c4131 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/office/service/OfficeWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/office/service/OfficeWritePlatformServiceJpaRepositoryImpl.java @@ -20,6 +20,9 @@ package org.apache.fineract.organisation.office.service; import java.util.Map; +import javax.persistence.PersistenceException; + +import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder; @@ -105,8 +108,12 @@ public class OfficeWritePlatformServiceJpaRepositoryImpl implements OfficeWriteP .withOfficeId(office.getId()) // .build(); } catch (final DataIntegrityViolationException dve) { - handleOfficeDataIntegrityIssues(command, dve); + handleOfficeDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleOfficeDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -148,8 +155,12 @@ public class OfficeWritePlatformServiceJpaRepositoryImpl implements OfficeWriteP .with(changes) // .build(); } catch (final DataIntegrityViolationException dve) { - handleOfficeDataIntegrityIssues(command, dve); + handleOfficeDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleOfficeDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -211,9 +222,8 @@ public class OfficeWritePlatformServiceJpaRepositoryImpl implements OfficeWriteP * Guaranteed to throw an exception no matter what the data integrity issue * is. */ - private void handleOfficeDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) { + private void handleOfficeDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dve) { - final Throwable realCause = dve.getMostSpecificCause(); if (realCause.getMessage().contains("externalid_org")) { final String externalId = command.stringValueOfParameterNamed("externalId"); throw new PlatformDataIntegrityException("error.msg.office.duplicate.externalId", "Office with externalId `" + externalId diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/provisioning/domain/LoanProductProvisionCriteria.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/provisioning/domain/LoanProductProvisionCriteria.java index 0ddf76267..042c4017f 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/provisioning/domain/LoanProductProvisionCriteria.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/provisioning/domain/LoanProductProvisionCriteria.java @@ -24,12 +24,12 @@ import javax.persistence.ManyToOne; import javax.persistence.Table; import javax.persistence.UniqueConstraint; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct; -import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @Table(name = "m_loanproduct_provisioning_mapping", uniqueConstraints = { @UniqueConstraint(columnNames = { "product_id" }, name = "product_id") }) -public class LoanProductProvisionCriteria extends AbstractPersistable { +public class LoanProductProvisionCriteria extends AbstractPersistableCustom { @ManyToOne(optional = false) @JoinColumn(name = "criteria_id", referencedColumnName = "id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/provisioning/domain/ProvisioningCategory.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/provisioning/domain/ProvisioningCategory.java index 7492d12a2..2c79dd8af 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/provisioning/domain/ProvisioningCategory.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/provisioning/domain/ProvisioningCategory.java @@ -27,11 +27,11 @@ import javax.persistence.Table; import javax.persistence.UniqueConstraint; import org.apache.fineract.infrastructure.core.api.JsonCommand; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_provision_category", uniqueConstraints = { @UniqueConstraint(columnNames = { "category_name" }, name = "category_name") }) -public class ProvisioningCategory extends AbstractPersistable { +public class ProvisioningCategory extends AbstractPersistableCustom { @Column(name = "category_name", nullable = false, unique = true) private String categoryName; diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/provisioning/domain/ProvisioningCriteria.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/provisioning/domain/ProvisioningCriteria.java index 320b3ccdd..e3de373f0 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/provisioning/domain/ProvisioningCriteria.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/provisioning/domain/ProvisioningCriteria.java @@ -116,7 +116,7 @@ public class ProvisioningCriteria extends AbstractAuditableCustom public void update(ProvisioningCriteriaDefinitionData data, GLAccount liability, GLAccount expense) { for(ProvisioningCriteriaDefinition def: provisioningCriteriaDefinition) { - if(data.getId() == def.getId()) { + if(data.getId().equals(def.getId())) { def.update(data.getMinAge(), data.getMaxAge(), data.getProvisioningPercentage(), liability, expense) ; break ; } diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/provisioning/domain/ProvisioningCriteriaDefinition.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/provisioning/domain/ProvisioningCriteriaDefinition.java index 01eb54bcd..28e065797 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/provisioning/domain/ProvisioningCriteriaDefinition.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/provisioning/domain/ProvisioningCriteriaDefinition.java @@ -20,6 +20,7 @@ package org.apache.fineract.organisation.provisioning.domain; import java.math.BigDecimal; +import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.JoinColumn; @@ -27,11 +28,11 @@ import javax.persistence.ManyToOne; import javax.persistence.Table; import org.apache.fineract.accounting.glaccount.domain.GLAccount; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_provisioning_criteria_definition") -public class ProvisioningCriteriaDefinition extends AbstractPersistable { +public class ProvisioningCriteriaDefinition extends AbstractPersistableCustom { @ManyToOne(optional = false) @JoinColumn(name = "criteria_id", referencedColumnName = "id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/provisioning/service/ProvisioningCategoryWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/provisioning/service/ProvisioningCategoryWritePlatformServiceJpaRepositoryImpl.java index 91dc24f66..8f7923607 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/provisioning/service/ProvisioningCategoryWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/provisioning/service/ProvisioningCategoryWritePlatformServiceJpaRepositoryImpl.java @@ -20,6 +20,9 @@ package org.apache.fineract.organisation.provisioning.service; import java.util.Map; +import javax.persistence.PersistenceException; + +import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder; @@ -65,8 +68,12 @@ public class ProvisioningCategoryWritePlatformServiceJpaRepositoryImpl implement return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(provisioningCategory.getId()) .build(); } catch (final DataIntegrityViolationException dve) { - handleDataIntegrityIssues(command, dve); + handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -96,8 +103,12 @@ public class ProvisioningCategoryWritePlatformServiceJpaRepositoryImpl implement } return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(categoryId).with(changes).build(); } catch (final DataIntegrityViolationException dve) { - handleDataIntegrityIssues(command, dve); + handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -110,9 +121,8 @@ public class ProvisioningCategoryWritePlatformServiceJpaRepositoryImpl implement * Guaranteed to throw an exception no matter what the data integrity issue * is. */ - private void handleDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) { + private void handleDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dve) { - final Throwable realCause = dve.getMostSpecificCause(); if (realCause.getMessage().contains("category_name")) { final String name = command.stringValueOfParameterNamed("category_name"); throw new PlatformDataIntegrityException("error.msg.provisioning.duplicate.categoryname", "Provisioning Cateory with name `" diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/provisioning/service/ProvisioningCriteriaWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/provisioning/service/ProvisioningCriteriaWritePlatformServiceJpaRepositoryImpl.java index 0c7f599b0..1be4d726a 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/provisioning/service/ProvisioningCriteriaWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/provisioning/service/ProvisioningCriteriaWritePlatformServiceJpaRepositoryImpl.java @@ -23,6 +23,9 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import javax.persistence.PersistenceException; + +import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.fineract.accounting.glaccount.domain.GLAccount; import org.apache.fineract.accounting.glaccount.domain.GLAccountRepository; import org.apache.fineract.accounting.provisioning.service.ProvisioningEntriesReadPlatformService; @@ -84,8 +87,12 @@ public class ProvisioningCriteriaWritePlatformServiceJpaRepositoryImpl implement this.provisioningCriteriaRepository.save(provisioningCriteria); return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(provisioningCriteria.getId()).build(); } catch (final DataIntegrityViolationException dve) { - handleDataIntegrityIssues(command, dve); + handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -114,12 +121,16 @@ public class ProvisioningCriteriaWritePlatformServiceJpaRepositoryImpl implement final Map changes = provisioningCriteria.update(command, products) ; if(!changes.isEmpty()) { updateProvisioningCriteriaDefinitions(provisioningCriteria, command) ; - provisioningCriteriaRepository.save(provisioningCriteria) ; + provisioningCriteriaRepository.saveAndFlush(provisioningCriteria) ; } return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(provisioningCriteria.getId()).build(); } catch (final DataIntegrityViolationException dve) { - handleDataIntegrityIssues(command, dve); + handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -153,9 +164,7 @@ public class ProvisioningCriteriaWritePlatformServiceJpaRepositoryImpl implement * Guaranteed to throw an exception no matter what the data integrity issue * is. */ - private void handleDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) { - - final Throwable realCause = dve.getMostSpecificCause(); + private void handleDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dve) { if (realCause.getMessage().contains("criteria_name")) { final String name = command.stringValueOfParameterNamed("criteria_name"); throw new PlatformDataIntegrityException("error.msg.provisioning.duplicate.criterianame", "Provisioning Criteria with name `" diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/staff/domain/Staff.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/staff/domain/Staff.java index d616ab4b8..64f6f90d0 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/staff/domain/Staff.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/staff/domain/Staff.java @@ -22,21 +22,29 @@ import java.util.Date; import java.util.LinkedHashMap; import java.util.Map; -import javax.persistence.*; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToOne; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.UniqueConstraint; import org.apache.commons.lang.StringUtils; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.EnumOptionData; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.infrastructure.documentmanagement.domain.Image; import org.apache.fineract.organisation.office.domain.Office; import org.joda.time.LocalDate; -import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @Table(name = "m_staff", uniqueConstraints = { @UniqueConstraint(columnNames = { "display_name" }, name = "display_name"), @UniqueConstraint(columnNames = { "external_id" }, name = "external_id_UNIQUE"), @UniqueConstraint(columnNames = { "mobile_no" }, name = "mobile_no_UNIQUE") }) -public class Staff extends AbstractPersistable { +public class Staff extends AbstractPersistableCustom { @Column(name = "firstname", length = 50) private String firstname; @@ -57,7 +65,7 @@ public class Staff extends AbstractPersistable { @JoinColumn(name = "office_id", nullable = false) private Office office; - @Column(name = "is_loan_officer ", nullable = false) + @Column(name = "is_loan_officer", nullable = false) private boolean loanOfficer; @Column(name = "organisational_role_enum", nullable = true) @@ -66,7 +74,7 @@ public class Staff extends AbstractPersistable { @Column(name = "is_active", nullable = false) private boolean active; - @Column(name = "joining_date", nullable = false) + @Column(name = "joining_date", nullable = true) @Temporal(TemporalType.DATE) private Date joiningDate; diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/staff/service/StaffWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/staff/service/StaffWritePlatformServiceJpaRepositoryImpl.java index b10dd12df..a46e90da5 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/staff/service/StaffWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/staff/service/StaffWritePlatformServiceJpaRepositoryImpl.java @@ -20,7 +20,10 @@ package org.apache.fineract.organisation.staff.service; import java.util.Map; +import javax.persistence.PersistenceException; + import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder; @@ -74,8 +77,12 @@ public class StaffWritePlatformServiceJpaRepositoryImpl implements StaffWritePla .withEntityId(staff.getId()).withOfficeId(officeId) // .build(); } catch (final DataIntegrityViolationException dve) { - handleStaffDataIntegrityIssues(command, dve); + handleStaffDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleStaffDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -104,8 +111,12 @@ public class StaffWritePlatformServiceJpaRepositoryImpl implements StaffWritePla return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(staffId) .withOfficeId(staffForUpdate.officeId()).with(changesOnly).build(); } catch (final DataIntegrityViolationException dve) { - handleStaffDataIntegrityIssues(command, dve); + handleStaffDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleStaffDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -113,8 +124,7 @@ public class StaffWritePlatformServiceJpaRepositoryImpl implements StaffWritePla * Guaranteed to throw an exception no matter what the data integrity issue * is. */ - private void handleStaffDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) { - final Throwable realCause = dve.getMostSpecificCause(); + private void handleStaffDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dve) { if (realCause.getMessage().contains("external_id")) { diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/domain/Cashier.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/domain/Cashier.java index cb2c16d69..1d5922faa 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/domain/Cashier.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/domain/Cashier.java @@ -22,7 +22,7 @@ import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.organisation.office.domain.Office; import org.apache.fineract.organisation.staff.domain.Staff; import org.joda.time.LocalDate; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import javax.persistence.*; import java.util.Date; @@ -40,7 +40,7 @@ import java.util.Map; @Entity @Table(name = "m_cashiers", uniqueConstraints = { @UniqueConstraint(name = "ux_cashiers_staff_teller", columnNames = { "staff_id", "teller_id" }) }) -public class Cashier extends AbstractPersistable { +public class Cashier extends AbstractPersistableCustom { // ManyToOne(fetch = FetchType.LAZY) // JoinColumn(name = "office_id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/domain/CashierTransaction.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/domain/CashierTransaction.java index 28ff20c78..65af4dde5 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/domain/CashierTransaction.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/domain/CashierTransaction.java @@ -22,7 +22,7 @@ package org.apache.fineract.organisation.teller.domain; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.organisation.office.domain.Office; import org.joda.time.LocalDate; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import javax.persistence.*; @@ -33,7 +33,7 @@ import java.util.Map; @Entity @Table(name = "m_cashier_transactions") -public class CashierTransaction extends AbstractPersistable { +public class CashierTransaction extends AbstractPersistableCustom { @Transient private Office office; @@ -58,10 +58,10 @@ public class CashierTransaction extends AbstractPersistable { @Column(name = "txn_note", nullable = true) private String txnNote; - @Column(name = "entity_type", nullable = false) + @Column(name = "entity_type", nullable = true) private String entityType; - @Column(name = "entity_id", nullable = false) + @Column(name = "entity_id", nullable = true) private Long entityId; @Temporal(TemporalType.TIMESTAMP) diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/domain/Teller.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/domain/Teller.java index ec3d0f3c1..b1fc196c5 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/domain/Teller.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/domain/Teller.java @@ -39,24 +39,24 @@ import org.apache.fineract.accounting.glaccount.domain.GLAccount; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.organisation.office.domain.Office; import org.joda.time.LocalDate; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_tellers", uniqueConstraints = { @UniqueConstraint(name = "ux_tellers_name", columnNames = {"name"}) }) -public class Teller extends AbstractPersistable { +public class Teller extends AbstractPersistableCustom { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "office_id", nullable = false) private Office office; - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "debit_account_id", nullable = false) + @ManyToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "debit_account_id", nullable = true) private GLAccount debitAccount; - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "credit_account_id", nullable = false) + @ManyToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "credit_account_id", nullable = true) private GLAccount creditAccount; @Column(name = "name", nullable = false, length = 100) @@ -66,11 +66,11 @@ public class Teller extends AbstractPersistable { private String description; @Temporal(TemporalType.TIMESTAMP) - @Column(name = "valid_from", nullable = false) + @Column(name = "valid_from", nullable = true) private Date startDate; @Temporal(TemporalType.TIMESTAMP) - @Column(name = "valid_to", nullable = false) + @Column(name = "valid_to", nullable = true) private Date endDate; @Column(name = "state", nullable = false) @@ -79,9 +79,6 @@ public class Teller extends AbstractPersistable { @OneToMany(mappedBy = "teller", fetch = FetchType.LAZY) private Set cashiers; - @OneToMany(mappedBy = "teller", fetch = FetchType.LAZY) - private Set tellerTransactions; - public Teller() { super(); } @@ -287,11 +284,8 @@ public class Teller extends AbstractPersistable { this.cashiers = cashiers; } - public Set getTransactions() { - return tellerTransactions; - } - - public void setTransactions(Set tellerTransactions) { - this.tellerTransactions = tellerTransactions; - } + public void initializeLazyCollections() { + this.office.getId(); + this.cashiers.size(); + } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/domain/TellerRepositoryWrapper.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/domain/TellerRepositoryWrapper.java index bb447bc28..183bc3e71 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/domain/TellerRepositoryWrapper.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/domain/TellerRepositoryWrapper.java @@ -21,6 +21,7 @@ package org.apache.fineract.organisation.teller.domain; import org.apache.fineract.organisation.teller.exception.TellerNotFoundException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; @Service public class TellerRepositoryWrapper { @@ -32,9 +33,23 @@ public class TellerRepositoryWrapper { this.repository = repository; } + @Transactional(readOnly=true) public Teller findOneWithNotFoundDetection(final Long id) { final Teller teller = this.repository.findOne(id); if (teller == null) { throw new TellerNotFoundException(id); } + teller.initializeLazyCollections(); return teller; } + + public Teller save(final Teller teller) { + return this.repository.save(teller) ; + } + + public Teller saveAndFlush(final Teller teller) { + return this.repository.saveAndFlush(teller) ; + } + + public void delete(final Teller teller) { + this.repository.delete(teller); + } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/domain/TellerTransaction.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/domain/TellerTransaction.java index 1b4aea97b..17be51c63 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/domain/TellerTransaction.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/domain/TellerTransaction.java @@ -20,14 +20,14 @@ package org.apache.fineract.organisation.teller.domain; import org.apache.fineract.organisation.office.domain.Office; import org.apache.fineract.portfolio.client.domain.Client; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import javax.persistence.*; import java.util.Date; @Entity @Table(name = "m_teller_transactions") -public class TellerTransaction extends AbstractPersistable { +public class TellerTransaction extends AbstractPersistableCustom { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "office_id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/service/TellerWritePlatformServiceJpaImpl.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/service/TellerWritePlatformServiceJpaImpl.java index bbaad9064..925fa118b 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/service/TellerWritePlatformServiceJpaImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/teller/service/TellerWritePlatformServiceJpaImpl.java @@ -21,6 +21,9 @@ package org.apache.fineract.organisation.teller.service; import java.util.Map; import java.util.Set; +import javax.persistence.PersistenceException; + +import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.fineract.accounting.common.AccountingConstants.FINANCIAL_ACTIVITY; import org.apache.fineract.accounting.financialactivityaccount.domain.FinancialActivityAccount; import org.apache.fineract.accounting.financialactivityaccount.domain.FinancialActivityAccountRepositoryWrapper; @@ -45,11 +48,9 @@ import org.apache.fineract.organisation.teller.domain.CashierTransaction; import org.apache.fineract.organisation.teller.domain.CashierTransactionRepository; import org.apache.fineract.organisation.teller.domain.CashierTxnType; import org.apache.fineract.organisation.teller.domain.Teller; -import org.apache.fineract.organisation.teller.domain.TellerRepository; import org.apache.fineract.organisation.teller.domain.TellerRepositoryWrapper; import org.apache.fineract.organisation.teller.exception.CashierExistForTellerException; import org.apache.fineract.organisation.teller.exception.CashierNotFoundException; -import org.apache.fineract.organisation.teller.exception.TellerNotFoundException; import org.apache.fineract.organisation.teller.serialization.TellerCommandFromApiJsonDeserializer; import org.apache.fineract.portfolio.client.domain.ClientTransaction; import org.apache.fineract.useradministration.domain.AppUser; @@ -67,7 +68,6 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer private final PlatformSecurityContext context; private final TellerCommandFromApiJsonDeserializer fromApiJsonDeserializer; - private final TellerRepository tellerRepository; private final TellerRepositoryWrapper tellerRepositoryWrapper; private final OfficeRepositoryWrapper officeRepositoryWrapper; private final StaffRepository staffRepository; @@ -78,14 +78,13 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer @Autowired public TellerWritePlatformServiceJpaImpl(final PlatformSecurityContext context, - final TellerCommandFromApiJsonDeserializer fromApiJsonDeserializer, final TellerRepository tellerRepository, + final TellerCommandFromApiJsonDeserializer fromApiJsonDeserializer, final TellerRepositoryWrapper tellerRepositoryWrapper, final OfficeRepositoryWrapper officeRepositoryWrapper, final StaffRepository staffRepository, CashierRepository cashierRepository, CashierTransactionRepository cashierTxnRepository, JournalEntryRepository glJournalEntryRepository, FinancialActivityAccountRepositoryWrapper financialActivityAccountRepositoryWrapper) { this.context = context; this.fromApiJsonDeserializer = fromApiJsonDeserializer; - this.tellerRepository = tellerRepository; this.tellerRepositoryWrapper = tellerRepositoryWrapper; this.officeRepositoryWrapper = officeRepositoryWrapper; this.staffRepository = staffRepository; @@ -111,7 +110,7 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer final Teller teller = Teller.fromJson(tellerOffice, command); // pre save to generate id for use in office hierarchy - this.tellerRepository.save(teller); + this.tellerRepositoryWrapper.save(teller); return new CommandProcessingResultBuilder() // .withCommandId(command.commandId()) // @@ -119,8 +118,12 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer .withOfficeId(teller.getOffice().getId()) // .build(); } catch (final DataIntegrityViolationException dve) { - handleTellerDataIntegrityIssues(command, dve); + handleTellerDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleTellerDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -140,7 +143,7 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer final Map changes = teller.update(tellerOffice, command); if (!changes.isEmpty()) { - this.tellerRepository.saveAndFlush(teller); + this.tellerRepositoryWrapper.saveAndFlush(teller); } return new CommandProcessingResultBuilder() // @@ -150,8 +153,12 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer .with(changes) // .build(); } catch (final DataIntegrityViolationException dve) { - handleTellerDataIntegrityIssues(command, dve); + handleTellerDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleTellerDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -163,15 +170,10 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer final Long userOfficeId = currentUser.getOffice().getId(); final Office userOffice = this.officeRepositoryWrapper.findOfficeHierarchy(userOfficeId); - final Teller tellerToReturn = this.tellerRepository.findOne(tellerId); - if (tellerToReturn != null) { - final Long tellerOfficeId = tellerToReturn.officeId(); - if (userOffice.doesNotHaveAnOfficeInHierarchyWithId(tellerOfficeId)) { throw new NoAuthorizationException( + final Teller tellerToReturn = this.tellerRepositoryWrapper.findOneWithNotFoundDetection(tellerId); + final Long tellerOfficeId = tellerToReturn.officeId(); + if (userOffice.doesNotHaveAnOfficeInHierarchyWithId(tellerOfficeId)) { throw new NoAuthorizationException( "User does not have sufficient priviledges to act on the provided office."); } - } else { - throw new TellerNotFoundException(tellerId); - } - return tellerToReturn; } @@ -188,7 +190,7 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer .equalsIgnoreCase(tellerId.toString())) { throw new CashierExistForTellerException(tellerId); } } - tellerRepository.delete(teller); + tellerRepositoryWrapper.delete(teller); return new CommandProcessingResultBuilder() // .withEntityId(teller.getId()) // .build(); @@ -199,9 +201,8 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer * Guaranteed to throw an exception no matter what the data integrity issue * is. */ - private void handleTellerDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) { + private void handleTellerDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dve) { - final Throwable realCause = dve.getMostSpecificCause(); if (realCause.getMessage().contains("m_tellers_name_unq")) { final String name = command.stringValueOfParameterNamed("name"); throw new PlatformDataIntegrityException("error.msg.teller.duplicate.name", "Teller with name `" + name + "` already exists", @@ -223,8 +224,7 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer Long minEndTime; String startTime = " "; String endTime = " "; - final Teller teller = this.tellerRepository.findOne(tellerId); - if (teller == null) { throw new TellerNotFoundException(tellerId); } + final Teller teller = this.tellerRepositoryWrapper.findOneWithNotFoundDetection(tellerId); final Office tellerOffice = teller.getOffice(); final Long staffId = command.longValueOfParameterNamed("staffId"); @@ -262,8 +262,12 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer .withSubEntityId(cashier.getId()) // .build(); } catch (final DataIntegrityViolationException dve) { - handleTellerDataIntegrityIssues(command, dve); + handleTellerDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleTellerDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -298,8 +302,12 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer .with(changes) // .build(); } catch (final DataIntegrityViolationException dve) { - handleTellerDataIntegrityIssues(command, dve); + handleTellerDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleTellerDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -321,8 +329,12 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer this.cashierRepository.delete(cashier); } catch (final DataIntegrityViolationException dve) { - handleTellerDataIntegrityIssues(command, dve); + handleTellerDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleTellerDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } return new CommandProcessingResultBuilder() // @@ -444,8 +456,12 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer .withSubEntityId(cashierTxn.getId()) // .build(); } catch (final DataIntegrityViolationException dve) { - handleTellerDataIntegrityIssues(command, dve); + handleTellerDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleTellerDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/domain/WorkingDays.java b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/domain/WorkingDays.java index adeba4a19..9562719f9 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/domain/WorkingDays.java +++ b/fineract-provider/src/main/java/org/apache/fineract/organisation/workingdays/domain/WorkingDays.java @@ -20,7 +20,7 @@ package org.apache.fineract.organisation.workingdays.domain; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.organisation.workingdays.api.WorkingDaysApiConstants; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import javax.persistence.Column; import javax.persistence.Entity; @@ -31,7 +31,7 @@ import java.util.Map; @Entity @Table(name = "m_working_days") -public class WorkingDays extends AbstractPersistable { +public class WorkingDays extends AbstractPersistableCustom { @Column(name = "recurrence", length = 100, nullable = true) private String recurrence; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountAssociations.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountAssociations.java index 82574bbc9..089139734 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountAssociations.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountAssociations.java @@ -26,11 +26,11 @@ import javax.persistence.Table; import org.apache.fineract.portfolio.loanaccount.domain.Loan; import org.apache.fineract.portfolio.savings.domain.SavingsAccount; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_portfolio_account_associations") -public class AccountAssociations extends AbstractPersistable { +public class AccountAssociations extends AbstractPersistableCustom { @ManyToOne @JoinColumn(name = "loan_account_id", nullable = true) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountAssociationsRepository.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountAssociationsRepository.java index 141a8bdd7..00266c476 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountAssociationsRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountAssociationsRepository.java @@ -26,9 +26,9 @@ import org.springframework.data.repository.query.Param; public interface AccountAssociationsRepository extends JpaRepository, JpaSpecificationExecutor { - @Query("from AccountAssociations aa where aa.loanAccount.id= :loanId and aa.associationType = :associationType") + @Query("select aa from AccountAssociations aa where aa.loanAccount.id= :loanId and aa.associationType = :associationType") AccountAssociations findByLoanIdAndType(@Param("loanId") Long loanId, @Param("associationType") Integer accountAssociationType); - @Query("from AccountAssociations aa where aa.savingsAccount.id= :savingsId and aa.associationType = :associationType") + @Query("select aa from AccountAssociations aa where aa.savingsAccount.id= :savingsId and aa.associationType = :associationType") AccountAssociations findBySavingsIdAndType(@Param("savingsId") Long savingsId, @Param("associationType") Integer accountAssociationType); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountTransferDetails.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountTransferDetails.java index 3a19ce652..8ec66ca47 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountTransferDetails.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountTransferDetails.java @@ -35,11 +35,11 @@ import org.apache.fineract.organisation.office.domain.Office; import org.apache.fineract.portfolio.client.domain.Client; import org.apache.fineract.portfolio.loanaccount.domain.Loan; import org.apache.fineract.portfolio.savings.domain.SavingsAccount; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_account_transfer_details") -public class AccountTransferDetails extends AbstractPersistable { +public class AccountTransferDetails extends AbstractPersistableCustom { @ManyToOne @JoinColumn(name = "from_office_id", nullable = false) @@ -77,9 +77,9 @@ public class AccountTransferDetails extends AbstractPersistable { private Integer transferType; @OneToMany(cascade = CascadeType.ALL, mappedBy = "accountTransferDetails", orphanRemoval = true, fetch=FetchType.EAGER) - private final List accountTransferTransactions = new ArrayList<>(); + private List accountTransferTransactions = new ArrayList<>(); - @OneToOne(mappedBy = "accountTransferDetails", cascade = CascadeType.ALL, optional = true, orphanRemoval = true, fetch = FetchType.LAZY) + @OneToOne(mappedBy = "accountTransferDetails", cascade = CascadeType.ALL, optional = true, orphanRemoval = true, fetch = FetchType.EAGER) private AccountTransferStandingInstruction accountTransferStandingInstruction; public static AccountTransferDetails savingsToSavingsTransfer(final Office fromOffice, final Client fromClient, diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountTransferRepository.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountTransferRepository.java index 8158cb8c1..e790c4c3b 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountTransferRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountTransferRepository.java @@ -29,15 +29,15 @@ import org.springframework.data.repository.query.Param; public interface AccountTransferRepository extends JpaRepository, JpaSpecificationExecutor { - @Query("from AccountTransferTransaction att where att.accountTransferDetails.fromLoanAccount.id= :accountNumber and att.reversed=false") + @Query("select att from AccountTransferTransaction att where att.accountTransferDetails.fromLoanAccount.id= :accountNumber and att.reversed=false") List findByFromLoanId(@Param("accountNumber") Long accountNumber); - @Query("from AccountTransferTransaction att where (att.accountTransferDetails.fromLoanAccount.id= :accountNumber or att.accountTransferDetails.toLoanAccount.id=:accountNumber) and att.reversed=false order by att.id desc") + @Query("select att from AccountTransferTransaction att where (att.accountTransferDetails.fromLoanAccount.id= :accountNumber or att.accountTransferDetails.toLoanAccount.id=:accountNumber) and att.reversed=false order by att.id desc") List findAllByLoanId(@Param("accountNumber") Long accountNumber); - @Query("from AccountTransferTransaction att where att.toLoanTransaction.id= :loanTransactionId and att.reversed=false") + @Query("select att from AccountTransferTransaction att where att.toLoanTransaction.id= :loanTransactionId and att.reversed=false") AccountTransferTransaction findByToLoanTransactionId(@Param("loanTransactionId") Long loanTransactionId); - @Query("from AccountTransferTransaction att where att.fromLoanTransaction.id IN :loanTransactions and att.reversed=false") + @Query("select att from AccountTransferTransaction att where att.fromLoanTransaction.id IN :loanTransactions and att.reversed=false") List findByFromLoanTransactions(@Param("loanTransactions") Collection loanTransactions); } \ No newline at end of file diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountTransferStandingInstruction.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountTransferStandingInstruction.java index 4249338ef..2335789c5 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountTransferStandingInstruction.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountTransferStandingInstruction.java @@ -54,11 +54,11 @@ import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidati import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType; import org.joda.time.LocalDate; import org.joda.time.MonthDay; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_account_transfer_standing_instructions", uniqueConstraints = { @UniqueConstraint(columnNames = { "name" }, name = "name") }) -public class AccountTransferStandingInstruction extends AbstractPersistable { +public class AccountTransferStandingInstruction extends AbstractPersistableCustom { @ManyToOne @JoinColumn(name = "account_transfer_details_id", nullable = true) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountTransferTransaction.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountTransferTransaction.java index bcec4f40c..d5bbd3042 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountTransferTransaction.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/domain/AccountTransferTransaction.java @@ -35,11 +35,11 @@ import org.apache.fineract.organisation.monetary.domain.Money; import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction; import org.apache.fineract.portfolio.savings.domain.SavingsAccountTransaction; import org.joda.time.LocalDate; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_account_transfer_transaction") -public class AccountTransferTransaction extends AbstractPersistable { +public class AccountTransferTransaction extends AbstractPersistableCustom { @ManyToOne @JoinColumn(name = "account_transfer_details_id", nullable = true) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/domain/Address.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/domain/Address.java index 6143a5b81..85c39a216 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/domain/Address.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/domain/Address.java @@ -33,17 +33,17 @@ import javax.persistence.Table; import org.apache.fineract.infrastructure.codes.domain.CodeValue; import org.apache.fineract.infrastructure.core.api.JsonCommand; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.portfolio.client.domain.ClientAddress; import org.joda.time.LocalDate; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; -import org.springframework.data.jpa.domain.AbstractPersistable; import com.google.gson.JsonObject; @Entity @Table(name = "m_address") -public class Address extends AbstractPersistable { +public class Address extends AbstractPersistableCustom { /* * @OneToMany(mappedBy = "address", cascade = CascadeType.ALL) private diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/domain/FieldConfiguration.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/domain/FieldConfiguration.java index 8afcb93c4..7353c7ed2 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/domain/FieldConfiguration.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/address/domain/FieldConfiguration.java @@ -22,11 +22,11 @@ import javax.persistence.Entity; import javax.persistence.Table; import org.apache.fineract.infrastructure.core.api.JsonCommand; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_field_configuration") -public class FieldConfiguration extends AbstractPersistable { +public class FieldConfiguration extends AbstractPersistableCustom { private String entity; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/domain/CalendarHistory.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/domain/CalendarHistory.java index 93dc0bf29..e9d2cf472 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/domain/CalendarHistory.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/domain/CalendarHistory.java @@ -29,11 +29,11 @@ import javax.persistence.Temporal; import javax.persistence.TemporalType; import org.joda.time.LocalDate; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_calendar_history") -public class CalendarHistory extends AbstractPersistable { +public class CalendarHistory extends AbstractPersistableCustom { @ManyToOne(optional = false) @JoinColumn(name = "calendar_id", referencedColumnName = "id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/domain/CalendarInstance.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/domain/CalendarInstance.java index 6ae6c60d5..b9ce4e3e1 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/domain/CalendarInstance.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/domain/CalendarInstance.java @@ -25,11 +25,11 @@ import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_calendar_instance") -public class CalendarInstance extends AbstractPersistable { +public class CalendarInstance extends AbstractPersistableCustom { @ManyToOne(cascade = CascadeType.PERSIST) @JoinColumn(name = "calendar_id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/domain/CalendarInstanceRepository.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/domain/CalendarInstanceRepository.java index 8fe3c24b8..8b1ea7ec4 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/domain/CalendarInstanceRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/calendar/domain/CalendarInstanceRepository.java @@ -44,13 +44,13 @@ public interface CalendarInstanceRepository extends JpaRepository findByCalendarIdAndEntityTypeId(Long calendarId, Integer entityTypeId); /** Should use in clause, can I do it without creating a new class? **/ - @Query("from CalendarInstance ci where ci.entityId in (select id from Loan loan where loan.client.id = :clientId and loan.group.id = :groupId and (loan.loanStatus = 100 or loan.loanStatus = 200 or loan.loanStatus = 300)) and ci.entityTypeId = 3") + @Query("select ci from CalendarInstance ci where ci.entityId in (select id from Loan loan where loan.client.id = :clientId and loan.group.id = :groupId and (loan.loanStatus = 100 or loan.loanStatus = 200 or loan.loanStatus = 300)) and ci.entityTypeId = 3") List findCalendarInstancesForActiveLoansByGroupIdAndClientId(@Param("groupId") Long groupId, @Param("clientId") Long clientId); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/domain/Charge.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/domain/Charge.java index 3e20582e6..19c46b35d 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/domain/Charge.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/domain/Charge.java @@ -52,11 +52,11 @@ import org.apache.fineract.portfolio.loanaccount.domain.LoanCharge; import org.apache.fineract.portfolio.tax.data.TaxGroupData; import org.apache.fineract.portfolio.tax.domain.TaxGroup; import org.joda.time.MonthDay; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_charge", uniqueConstraints = { @UniqueConstraint(columnNames = { "name" }, name = "name") }) -public class Charge extends AbstractPersistable { +public class Charge extends AbstractPersistableCustom { @Column(name = "name", length = 100) private String name; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/service/ChargeReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/service/ChargeReadPlatformServiceImpl.java index 3366a2402..8d438ccca 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/service/ChargeReadPlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/service/ChargeReadPlatformServiceImpl.java @@ -89,7 +89,7 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService public Collection retrieveAllCharges() { final ChargeMapper rm = new ChargeMapper(); - String sql = "select " + rm.chargeSchema() + " where c.is_deleted=0 "; + String sql = "select " + rm.chargeSchema() + " where c.is_deleted=false "; sql += addInClauseToSQL_toLimitChargesMappedToOffice_ifOfficeSpecificProductsEnabled(); @@ -102,7 +102,7 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService public Collection retrieveAllChargesForCurrency(String currencyCode) { final ChargeMapper rm = new ChargeMapper(); - String sql = "select " + rm.chargeSchema() + " where c.is_deleted=0 and c.currency_code='" + currencyCode + "' "; + String sql = "select " + rm.chargeSchema() + " where c.is_deleted=false and c.currency_code='" + currencyCode + "' "; sql += addInClauseToSQL_toLimitChargesMappedToOffice_ifOfficeSpecificProductsEnabled(); @@ -116,10 +116,11 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService try { final ChargeMapper rm = new ChargeMapper(); - String sql = "select " + rm.chargeSchema() + " where c.id = ? and c.is_deleted=0 "; + String sql = "select " + rm.chargeSchema() + " where c.id = ? and c.is_deleted=false "; sql += addInClauseToSQL_toLimitChargesMappedToOffice_ifOfficeSpecificProductsEnabled(); + sql = sql + " ;" ; return this.jdbcTemplate.queryForObject(sql, rm, new Object[] { chargeId }); } catch (final EmptyResultDataAccessException e) { throw new ChargeNotFoundException(chargeId); @@ -162,7 +163,7 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService public Collection retrieveLoanProductCharges(final Long loanProductId) { final ChargeMapper rm = new ChargeMapper(); - String sql = "select " + rm.loanProductChargeSchema() + " where c.is_deleted=0 and c.is_active=1 and plc.product_loan_id=? "; + String sql = "select " + rm.loanProductChargeSchema() + " where c.is_deleted=false and c.is_active=true and plc.product_loan_id=? "; sql += addInClauseToSQL_toLimitChargesMappedToOffice_ifOfficeSpecificProductsEnabled(); @@ -175,7 +176,7 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService final ChargeMapper rm = new ChargeMapper(); String sql = "select " + rm.loanProductChargeSchema() - + " where c.is_deleted=0 and c.is_active=1 and plc.product_loan_id=? and c.charge_time_enum=? "; + + " where c.is_deleted=false and c.is_active=true and plc.product_loan_id=? and c.charge_time_enum=? "; sql += addInClauseToSQL_toLimitChargesMappedToOffice_ifOfficeSpecificProductsEnabled(); return this.jdbcTemplate.query(sql, rm, new Object[] { loanProductId, chargeTime.getValue() }); @@ -186,7 +187,7 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService final ChargeMapper rm = new ChargeMapper(); Object[] params = new Object[] { ChargeAppliesTo.LOAN.getValue() }; String sql = "select " + rm.chargeSchema() - + " where c.is_deleted=0 and c.is_active=1 and c.is_penalty=0 and c.charge_applies_to_enum=? "; + + " where c.is_deleted=false and c.is_active=true and c.is_penalty=false and c.charge_applies_to_enum=? "; sql += addInClauseToSQL_toLimitChargesMappedToOffice_ifOfficeSpecificProductsEnabled(); sql += " order by c.name "; @@ -202,7 +203,7 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService paramMap.put("chargeAppliesTo", ChargeAppliesTo.LOAN.getValue()); processChargeExclusionsForLoans(excludeChargeTimes, excludeClause); String sql = "select " + rm.chargeSchema() + " join m_loan la on la.currency_code = c.currency_code" + " where la.id=:loanId" - + " and c.is_deleted=0 and c.is_active=1 and c.charge_applies_to_enum=:chargeAppliesTo" + excludeClause + " "; + + " and c.is_deleted=false and c.is_active=true and c.charge_applies_to_enum=:chargeAppliesTo" + excludeClause + " "; sql += addInClauseToSQL_toLimitChargesMappedToOffice_ifOfficeSpecificProductsEnabled(); sql += " order by c.name "; return this.namedParameterJdbcTemplate.query(sql, paramMap, rm); @@ -236,7 +237,7 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService paramMap.put("chargeAppliesTo", ChargeAppliesTo.LOAN.getValue()); processChargeExclusionsForLoans(excludeChargeTimes, excludeClause); String sql = "select " + rm.chargeSchema() + " join m_product_loan lp on lp.currency_code = c.currency_code" - + " where lp.id=:productId" + " and c.is_deleted=0 and c.is_active=1 and c.charge_applies_to_enum=:chargeAppliesTo" + + " where lp.id=:productId" + " and c.is_deleted=false and c.is_active=true and c.charge_applies_to_enum=:chargeAppliesTo" + excludeClause + " "; sql += addInClauseToSQL_toLimitChargesMappedToOffice_ifOfficeSpecificProductsEnabled(); sql += " order by c.name "; @@ -249,7 +250,7 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService final ChargeMapper rm = new ChargeMapper(); String sql = "select " + rm.chargeSchema() - + " where c.is_deleted=0 and c.is_active=1 and c.is_penalty=1 and c.charge_applies_to_enum=? "; + + " where c.is_deleted=false and c.is_active=true and c.is_penalty=true and c.charge_applies_to_enum=? "; sql += addInClauseToSQL_toLimitChargesMappedToOffice_ifOfficeSpecificProductsEnabled(); sql += " order by c.name "; return this.jdbcTemplate.query(sql, rm, new Object[] { ChargeAppliesTo.LOAN.getValue() }); @@ -372,10 +373,10 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService public Collection retrieveSavingsProductApplicableCharges(final boolean feeChargesOnly) { final ChargeMapper rm = new ChargeMapper(); - String sql = "select " + rm.chargeSchema() + " where c.is_deleted=0 and c.is_active=1 and c.charge_applies_to_enum=? "; + String sql = "select " + rm.chargeSchema() + " where c.is_deleted=false and c.is_active=true and c.charge_applies_to_enum=? "; if (feeChargesOnly) { sql = "select " + rm.chargeSchema() - + " where c.is_deleted=0 and c.is_active=1 and c.is_penalty=0 and c.charge_applies_to_enum=? "; + + " where c.is_deleted=false and c.is_active=true and c.is_penalty=false and c.charge_applies_to_enum=? "; } sql += addInClauseToSQL_toLimitChargesMappedToOffice_ifOfficeSpecificProductsEnabled(); sql += " order by c.name "; @@ -388,7 +389,7 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService final ChargeMapper rm = new ChargeMapper(); String sql = "select " + rm.chargeSchema() - + " where c.is_deleted=0 and c.is_active=1 and c.is_penalty=1 and c.charge_applies_to_enum=? "; + + " where c.is_deleted=false and c.is_active=true and c.is_penalty=true and c.charge_applies_to_enum=? "; sql += addInClauseToSQL_toLimitChargesMappedToOffice_ifOfficeSpecificProductsEnabled(); sql += " order by c.name "; return this.jdbcTemplate.query(sql, rm, new Object[] { ChargeAppliesTo.SAVINGS.getValue() }); @@ -408,7 +409,7 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService public Collection retrieveShareProductCharges(final Long shareProductId) { final ChargeMapper rm = new ChargeMapper(); - String sql = "select " + rm.shareProductChargeSchema() + " where c.is_deleted=0 and c.is_active=1 and mspc.product_id=? "; + String sql = "select " + rm.shareProductChargeSchema() + " where c.is_deleted=false and c.is_active=true and mspc.product_id=? "; sql += addInClauseToSQL_toLimitChargesMappedToOffice_ifOfficeSpecificProductsEnabled(); return this.jdbcTemplate.query(sql, rm, new Object[] { shareProductId }); @@ -420,7 +421,7 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService final ChargeMapper rm = new ChargeMapper(); String sql = "select " + rm.chargeSchema() + " join m_savings_account sa on sa.currency_code = c.currency_code" - + " where c.is_deleted=0 and c.is_active=1 and c.charge_applies_to_enum=? " + " and sa.id = ?"; + + " where c.is_deleted=false and c.is_active=true and c.charge_applies_to_enum=? " + " and sa.id = ?"; sql += addInClauseToSQL_toLimitChargesMappedToOffice_ifOfficeSpecificProductsEnabled(); return this.jdbcTemplate.query(sql, rm, new Object[] { ChargeAppliesTo.SAVINGS.getValue(), savingsAccountId }); @@ -430,7 +431,7 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService @Override public Collection retrieveAllChargesApplicableToClients() { final ChargeMapper rm = new ChargeMapper(); - String sql = "select " + rm.chargeSchema() + " where c.is_deleted=0 and c.is_active=1 and c.charge_applies_to_enum=? "; + String sql = "select " + rm.chargeSchema() + " where c.is_deleted=false and c.is_active=true and c.charge_applies_to_enum=? "; sql += addInClauseToSQL_toLimitChargesMappedToOffice_ifOfficeSpecificProductsEnabled(); sql += " order by c.name "; @@ -440,7 +441,7 @@ public class ChargeReadPlatformServiceImpl implements ChargeReadPlatformService @Override public Collection retrieveSharesApplicableCharges() { final ChargeMapper rm = new ChargeMapper(); - String sql = "select " + rm.chargeSchema() + " where c.is_deleted=0 and c.is_active=1 and c.charge_applies_to_enum=? "; + String sql = "select " + rm.chargeSchema() + " where c.is_deleted=false and c.is_active=true and c.charge_applies_to_enum=? "; sql += addInClauseToSQL_toLimitChargesMappedToOffice_ifOfficeSpecificProductsEnabled(); sql += " order by c.name "; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/service/ChargeWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/service/ChargeWritePlatformServiceJpaRepositoryImpl.java index fdc14cfc2..bfa2c5d15 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/service/ChargeWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/charge/service/ChargeWritePlatformServiceJpaRepositoryImpl.java @@ -21,8 +21,10 @@ package org.apache.fineract.portfolio.charge.service; import java.util.Collection; import java.util.Map; +import javax.persistence.PersistenceException; import javax.sql.DataSource; +import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.fineract.accounting.glaccount.domain.GLAccount; import org.apache.fineract.accounting.glaccount.domain.GLAccountRepositoryWrapper; import org.apache.fineract.infrastructure.core.api.JsonCommand; @@ -31,7 +33,6 @@ import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuild import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException; import org.apache.fineract.infrastructure.core.service.RoutingDataSource; import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntityAccessType; -import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntityType; import org.apache.fineract.infrastructure.entityaccess.service.FineractEntityAccessUtil; import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; import org.apache.fineract.portfolio.charge.api.ChargesApiConstants; @@ -117,9 +118,13 @@ public class ChargeWritePlatformServiceJpaRepositoryImpl implements ChargeWriteP FineractEntityAccessType.OFFICE_ACCESS_TO_CHARGES, charge.getId()); return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(charge.getId()).build(); - } catch (final DataIntegrityViolationException dve) { - handleDataIntegrityIssues(command, dve); + }catch (final DataIntegrityViolationException dve) { + handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch(final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -184,8 +189,12 @@ public class ChargeWritePlatformServiceJpaRepositoryImpl implements ChargeWriteP return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(chargeId).with(changes).build(); } catch (final DataIntegrityViolationException dve) { - handleDataIntegrityIssues(command, dve); + handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch(final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -217,9 +226,8 @@ public class ChargeWritePlatformServiceJpaRepositoryImpl implements ChargeWriteP * Guaranteed to throw an exception no matter what the data integrity issue * is. */ - private void handleDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) { + private void handleDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dve) { - final Throwable realCause = dve.getMostSpecificCause(); if (realCause.getMessage().contains("name")) { final String name = command.stringValueOfParameterNamed("name"); throw new PlatformDataIntegrityException("error.msg.charge.duplicate.name", "Charge with name `" + name + "` already exists", diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/Client.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/Client.java index a857b4bff..053045244 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/Client.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/Client.java @@ -57,12 +57,12 @@ import org.apache.fineract.portfolio.group.domain.Group; import org.apache.fineract.useradministration.domain.AppUser; import org.joda.time.LocalDate; import org.joda.time.format.DateTimeFormatter; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_client", uniqueConstraints = { @UniqueConstraint(columnNames = { "account_no" }, name = "account_no_UNIQUE"), // @UniqueConstraint(columnNames = { "mobile_no" }, name = "mobile_no_UNIQUE") }) -public final class Client extends AbstractPersistable { +public final class Client extends AbstractPersistableCustom { @Column(name = "account_no", length = 20, unique = true, nullable = false) private String accountNumber; @@ -153,7 +153,7 @@ public final class Client extends AbstractPersistable { @Temporal(TemporalType.DATE) private Date rejectionDate; - @ManyToOne(optional = true) + @ManyToOne(optional = true, fetch=FetchType.LAZY) @JoinColumn(name = "rejectedon_userid", nullable = true) private AppUser rejectedBy; @@ -165,7 +165,7 @@ public final class Client extends AbstractPersistable { @Temporal(TemporalType.DATE) private Date withdrawalDate; - @ManyToOne(optional = true) + @ManyToOne(optional = true, fetch=FetchType.LAZY) @JoinColumn(name = "withdraw_on_userid", nullable = true) private AppUser withdrawnBy; @@ -173,11 +173,11 @@ public final class Client extends AbstractPersistable { @Temporal(TemporalType.DATE) private Date reactivateDate; - @ManyToOne(optional = true) + @ManyToOne(optional = true, fetch=FetchType.LAZY) @JoinColumn(name = "reactivated_on_userid", nullable = true) private AppUser reactivatedBy; - @ManyToOne(optional = true) + @ManyToOne(optional = true, fetch=FetchType.LAZY) @JoinColumn(name = "closedon_userid", nullable = true) private AppUser closedBy; @@ -185,7 +185,7 @@ public final class Client extends AbstractPersistable { @Temporal(TemporalType.DATE) private Date submittedOnDate; - @ManyToOne(optional = true) + @ManyToOne(optional = true, fetch=FetchType.LAZY) @JoinColumn(name = "submittedon_userid", nullable = true) private AppUser submittedBy; @@ -193,11 +193,11 @@ public final class Client extends AbstractPersistable { @Temporal(TemporalType.DATE) private Date updatedOnDate; - @ManyToOne(optional = true) + @ManyToOne(optional = true, fetch=FetchType.LAZY) @JoinColumn(name = "updated_by", nullable = true) private AppUser updatedBy; - @ManyToOne(optional = true) + @ManyToOne(optional = true, fetch=FetchType.LAZY) @JoinColumn(name = "activatedon_userid", nullable = true) private AppUser activatedBy; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientAddress.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientAddress.java index a9624b5d0..5eff17309 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientAddress.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientAddress.java @@ -25,12 +25,12 @@ import javax.persistence.ManyToOne; import javax.persistence.Table; import org.apache.fineract.infrastructure.codes.domain.CodeValue; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.portfolio.address.domain.Address; -import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @Table(name = "m_client_address") -public class ClientAddress extends AbstractPersistable { +public class ClientAddress extends AbstractPersistableCustom { @ManyToOne private Client client; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientCharge.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientCharge.java index 1410c5f99..23743366f 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientCharge.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientCharge.java @@ -39,11 +39,11 @@ import org.apache.fineract.portfolio.charge.domain.ChargeCalculationType; import org.apache.fineract.portfolio.charge.domain.ChargeTimeType; import org.apache.fineract.portfolio.client.api.ClientApiConstants; import org.joda.time.LocalDate; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_client_charge") -public class ClientCharge extends AbstractPersistable { +public class ClientCharge extends AbstractPersistableCustom { @ManyToOne(optional = false) @JoinColumn(name = "client_id", referencedColumnName = "id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientChargePaidBy.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientChargePaidBy.java index de036a7e9..3cdfdf575 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientChargePaidBy.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientChargePaidBy.java @@ -26,11 +26,11 @@ import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_client_charge_paid_by") -public class ClientChargePaidBy extends AbstractPersistable { +public class ClientChargePaidBy extends AbstractPersistableCustom { @ManyToOne @JoinColumn(name = "client_transaction_id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientNonPerson.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientNonPerson.java index 541d3bb02..23e18ef7e 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientNonPerson.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientNonPerson.java @@ -42,11 +42,11 @@ import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_client_non_person") -public class ClientNonPerson extends AbstractPersistable { +public class ClientNonPerson extends AbstractPersistableCustom { @OneToOne(optional = false) @JoinColumn(name = "client_id", referencedColumnName = "id", nullable = false, unique = true) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientNonPersonRepository.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientNonPersonRepository.java index c9723f887..d80653013 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientNonPersonRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientNonPersonRepository.java @@ -25,6 +25,6 @@ import org.springframework.data.repository.query.Param; public interface ClientNonPersonRepository extends JpaRepository, JpaSpecificationExecutor{ - @Query("from ClientNonPerson clientNonPerson where clientNonPerson.client.id = :clientId") + @Query("select clientNonPerson from ClientNonPerson clientNonPerson where clientNonPerson.client.id = :clientId") ClientNonPerson findByClientId(@Param("clientId") Long clientId); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientTransaction.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientTransaction.java index 65a0e36e8..c8e726615 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientTransaction.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientTransaction.java @@ -50,11 +50,11 @@ import org.apache.fineract.organisation.office.domain.OrganisationCurrency; import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail; import org.apache.fineract.useradministration.domain.AppUser; import org.joda.time.LocalDate; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_client_transaction", uniqueConstraints = { @UniqueConstraint(columnNames = { "external_id" }, name = "external_id") }) -public class ClientTransaction extends AbstractPersistable { +public class ClientTransaction extends AbstractPersistableCustom { @ManyToOne(optional = false) @JoinColumn(name = "client_id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientTransactionRepositoryWrapper.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientTransactionRepositoryWrapper.java index 028b5c665..3dede2f80 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientTransactionRepositoryWrapper.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/domain/ClientTransactionRepositoryWrapper.java @@ -39,7 +39,7 @@ public class ClientTransactionRepositoryWrapper { public ClientTransaction findOneWithNotFoundDetection(final Long clientId, final Long transactionId) { final ClientTransaction clientTransaction = this.repository.findOne(transactionId); if (clientTransaction == null - || clientTransaction.getClientId() != clientId) { throw new ClientTransactionNotFoundException(clientId, transactionId); } + || !clientTransaction.getClientId().equals(clientId)) { throw new ClientTransactionNotFoundException(clientId, transactionId); } // enrich Client charge with details of Organizational currency clientTransaction.setCurrency(organisationCurrencyRepository.findOneWithNotFoundDetection(clientTransaction.getCurrencyCode())); return clientTransaction; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientChargeWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientChargeWritePlatformServiceJpaRepositoryImpl.java index 09ee4f167..8ba80717a 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientChargeWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientChargeWritePlatformServiceJpaRepositoryImpl.java @@ -121,8 +121,7 @@ public class ClientChargeWritePlatformServiceJpaRepositoryImpl implements Client final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()); validateDueDateOnWorkingDay(clientCharge, fmt); - - this.clientChargeRepository.save(clientCharge); + this.clientChargeRepository.saveAndFlush(clientCharge); return new CommandProcessingResultBuilder() // .withEntityId(clientCharge.getId()) // diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientIdentifierWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientIdentifierWritePlatformServiceJpaRepositoryImpl.java index ef14d6301..33ec3fd7f 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientIdentifierWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientIdentifierWritePlatformServiceJpaRepositoryImpl.java @@ -20,6 +20,9 @@ package org.apache.fineract.portfolio.client.service; import java.util.Map; +import javax.persistence.PersistenceException; + +import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.fineract.infrastructure.codes.domain.CodeValue; import org.apache.fineract.infrastructure.codes.domain.CodeValueRepositoryWrapper; import org.apache.fineract.infrastructure.codes.exception.CodeValueNotFoundException; @@ -97,9 +100,12 @@ public class ClientIdentifierWritePlatformServiceJpaRepositoryImpl implements Cl .withEntityId(clientIdentifier.getId()) // .build(); } catch (final DataIntegrityViolationException dve) { - handleClientIdentifierDataIntegrityViolation(documentTypeLabel, documentTypeId, documentKey, dve); - + handleClientIdentifierDataIntegrityViolation(documentTypeLabel, documentTypeId, documentKey, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch(final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleClientIdentifierDataIntegrityViolation(documentTypeLabel, documentTypeId, documentKey, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -156,8 +162,12 @@ public class ClientIdentifierWritePlatformServiceJpaRepositoryImpl implements Cl .with(changes) // .build(); } catch (final DataIntegrityViolationException dve) { - handleClientIdentifierDataIntegrityViolation(documentTypeLabel, documentTypeId, documentKey, dve); + handleClientIdentifierDataIntegrityViolation(documentTypeLabel, documentTypeId, documentKey, dve.getMostSpecificCause(), dve); return new CommandProcessingResult(Long.valueOf(-1)); + }catch(final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleClientIdentifierDataIntegrityViolation(documentTypeLabel, documentTypeId, documentKey, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -180,11 +190,10 @@ public class ClientIdentifierWritePlatformServiceJpaRepositoryImpl implements Cl } private void handleClientIdentifierDataIntegrityViolation(final String documentTypeLabel, final Long documentTypeId, - final String documentKey, final DataIntegrityViolationException dve) { - - if (dve.getMostSpecificCause().getMessage().contains("unique_active_client_identifier")) { + final String documentKey, final Throwable cause, final Exception dve) { + if (cause.getMessage().contains("unique_active_client_identifier")) { throw new DuplicateClientIdentifierException(documentTypeLabel); - } else if (dve.getMostSpecificCause().getMessage().contains("unique_identifier_key")) { throw new DuplicateClientIdentifierException( + } else if (cause.getMessage().contains("unique_identifier_key")) { throw new DuplicateClientIdentifierException( documentTypeId, documentTypeLabel, documentKey); } logAsErrorUnexpectedDataIntegrityException(dve); @@ -192,7 +201,7 @@ public class ClientIdentifierWritePlatformServiceJpaRepositoryImpl implements Cl "Unknown data integrity issue with resource."); } - private void logAsErrorUnexpectedDataIntegrityException(final DataIntegrityViolationException dve) { + private void logAsErrorUnexpectedDataIntegrityException(final Exception dve) { logger.error(dve.getMessage(), dve); } } \ No newline at end of file diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java index 3e9c1c746..3c620abb7 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java @@ -24,6 +24,9 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import javax.persistence.PersistenceException; + +import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.fineract.commands.domain.CommandWrapper; import org.apache.fineract.commands.service.CommandProcessingService; import org.apache.fineract.commands.service.CommandWrapperBuilder; @@ -176,9 +179,8 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP * Guaranteed to throw an exception no matter what the data integrity issue * is. */ - private void handleDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) { + private void handleDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dve) { - final Throwable realCause = dve.getMostSpecificCause(); if (realCause.getMessage().contains("external_id")) { final String externalId = command.stringValueOfParameterNamed("externalId"); @@ -316,8 +318,12 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP .setRollbackTransaction(result.isRollbackTransaction())// .build(); } catch (final DataIntegrityViolationException dve) { - handleDataIntegrityIssues(command, dve); + handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch(final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -500,8 +506,12 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP .with(changes) // .build(); } catch (final DataIntegrityViolationException dve) { - handleDataIntegrityIssues(command, dve); + handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch(final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -532,7 +542,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP .setRollbackTransaction(result.isRollbackTransaction())// .build(); } catch (final DataIntegrityViolationException dve) { - handleDataIntegrityIssues(command, dve); + handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); } } @@ -552,7 +562,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP return commandProcessingResult; } - private void logAsErrorUnexpectedDataIntegrityException(final DataIntegrityViolationException dve) { + private void logAsErrorUnexpectedDataIntegrityException(final Exception dve) { logger.error(dve.getMessage(), dve); } @@ -686,7 +696,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP .withEntityId(clientId) // .build(); } catch (final DataIntegrityViolationException dve) { - handleDataIntegrityIssues(command, dve); + handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/collateral/domain/LoanCollateral.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/collateral/domain/LoanCollateral.java index 1f787a5f0..6f86ef02d 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/collateral/domain/LoanCollateral.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/collateral/domain/LoanCollateral.java @@ -29,19 +29,17 @@ import javax.persistence.ManyToOne; import javax.persistence.Table; import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.fineract.infrastructure.codes.data.CodeValueData; import org.apache.fineract.infrastructure.codes.domain.CodeValue; import org.apache.fineract.infrastructure.core.api.JsonCommand; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.portfolio.collateral.api.CollateralApiConstants.COLLATERAL_JSON_INPUT_PARAMS; import org.apache.fineract.portfolio.collateral.data.CollateralData; import org.apache.fineract.portfolio.loanaccount.domain.Loan; -import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @Table(name = "m_loan_collateral") -public class LoanCollateral extends AbstractPersistable { +public class LoanCollateral extends AbstractPersistableCustom { @ManyToOne(optional = false) @JoinColumn(name = "loan_id", nullable = false) @@ -124,7 +122,7 @@ public class LoanCollateral extends AbstractPersistable { this.type = type; } - @Override + /* @Override public boolean equals(final Object obj) { if (obj == null) { return false; } if (obj == this) { return true; } @@ -146,5 +144,5 @@ public class LoanCollateral extends AbstractPersistable { .append(this.description) // .append(this.value)// .toHashCode(); - } + }*/ } \ No newline at end of file diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/domain/FloatingRate.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/domain/FloatingRate.java index 6275074b8..191347957 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/domain/FloatingRate.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/domain/FloatingRate.java @@ -19,33 +19,18 @@ package org.apache.fineract.portfolio.floatingrates.domain; import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Set; +import java.util.*; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.OrderBy; -import javax.persistence.Table; -import javax.persistence.UniqueConstraint; +import javax.persistence.*; import org.apache.fineract.infrastructure.core.api.JsonCommand; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.infrastructure.core.serialization.JsonParserHelper; import org.apache.fineract.infrastructure.core.service.DateUtils; import org.apache.fineract.portfolio.floatingrates.data.FloatingRateDTO; import org.apache.fineract.portfolio.floatingrates.data.FloatingRatePeriodData; import org.apache.fineract.useradministration.domain.AppUser; import org.joda.time.LocalDate; -import org.springframework.data.jpa.domain.AbstractPersistable; import com.google.gson.JsonArray; import com.google.gson.JsonElement; @@ -53,7 +38,7 @@ import com.google.gson.JsonObject; @Entity @Table(name = "m_floating_rates", uniqueConstraints = { @UniqueConstraint(columnNames = { "name" }, name = "unq_name") }) -public class FloatingRate extends AbstractPersistable { +public class FloatingRate extends AbstractPersistableCustom { @Column(name = "name", length = 200, unique = true, nullable = false) private String name; @@ -66,13 +51,13 @@ public class FloatingRate extends AbstractPersistable { @OrderBy(value = "fromDate,id") @OneToMany(cascade = CascadeType.ALL, mappedBy = "floatingRate", orphanRemoval = true, fetch=FetchType.EAGER) - private Set floatingRatePeriods; + private List floatingRatePeriods; - @ManyToOne(optional = true) + @ManyToOne(optional = true, fetch=FetchType.LAZY) @JoinColumn(name = "createdby_id", nullable = false) private AppUser createdBy; - @ManyToOne(optional = true) + @ManyToOne(optional = true, fetch=FetchType.LAZY) @JoinColumn(name = "lastmodifiedby_id", nullable = false) private AppUser modifiedBy; @@ -87,7 +72,7 @@ public class FloatingRate extends AbstractPersistable { } public FloatingRate(String name, boolean isBaseLendingRate, - boolean isActive, Set floatingRatePeriods, + boolean isActive, List floatingRatePeriods, AppUser createdBy, AppUser modifiedBy, Date createdOn, Date modifiedOn) { this.name = name; @@ -115,7 +100,7 @@ public class FloatingRate extends AbstractPersistable { : false; final boolean isActive = command.parameterExists("isActive") ? command .booleanPrimitiveValueOfParameterNamed("isActive") : true; - final Set floatingRatePeriods = getRatePeriods( + final List floatingRatePeriods = getRatePeriods( currentUser, command); final LocalDate currentDate = DateUtils.getLocalDateOfTenant(); @@ -124,12 +109,12 @@ public class FloatingRate extends AbstractPersistable { currentDate.toDate(), currentDate.toDate()); } - private static Set getRatePeriods( + private static List getRatePeriods( final AppUser currentUser, final JsonCommand command) { if (!command.parameterExists("ratePeriods")) { return null; } - Set ratePeriods = new HashSet<>(); + List ratePeriods = new ArrayList<>(); JsonArray arrayOfParameterNamed = command .arrayOfParameterNamed("ratePeriods"); for (final JsonElement ratePeriod : arrayOfParameterNamed) { @@ -165,7 +150,7 @@ public class FloatingRate extends AbstractPersistable { return this.isActive; } - public Set getFloatingRatePeriods() { + public List getFloatingRatePeriods() { return this.floatingRatePeriods; } @@ -211,7 +196,7 @@ public class FloatingRate extends AbstractPersistable { this.isActive = newValue; } - final Set newRatePeriods = getRatePeriods(appUser, + final List newRatePeriods = getRatePeriods(appUser, command); if (newRatePeriods != null && !newRatePeriods.isEmpty()) { updateRatePeriods(newRatePeriods, appUser); @@ -223,7 +208,7 @@ public class FloatingRate extends AbstractPersistable { } private void updateRatePeriods( - final Set newRatePeriods, final AppUser appUser) { + final List newRatePeriods, final AppUser appUser) { final LocalDate today = DateUtils.getLocalDateOfTenant(); if (this.floatingRatePeriods != null) { for (FloatingRatePeriod ratePeriod : this.floatingRatePeriods) { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/domain/FloatingRatePeriod.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/domain/FloatingRatePeriod.java index d7dbb357b..f9e0b4590 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/domain/FloatingRatePeriod.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/domain/FloatingRatePeriod.java @@ -23,20 +23,21 @@ import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.FetchType; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.portfolio.floatingrates.data.FloatingRateDTO; import org.apache.fineract.portfolio.floatingrates.data.FloatingRatePeriodData; import org.apache.fineract.useradministration.domain.AppUser; import org.joda.time.LocalDate; import org.joda.time.LocalDateTime; -import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @Table(name = "m_floating_rates_periods") -public class FloatingRatePeriod extends AbstractPersistable { +public class FloatingRatePeriod extends AbstractPersistableCustom { @ManyToOne @JoinColumn(name = "floating_rates_id", nullable = false) @@ -54,11 +55,11 @@ public class FloatingRatePeriod extends AbstractPersistable { @Column(name = "is_active", nullable = false) private boolean isActive; - @ManyToOne(optional = true) + @ManyToOne(optional = true, fetch=FetchType.LAZY) @JoinColumn(name = "createdby_id", nullable = false) private AppUser createdBy; - @ManyToOne(optional = true) + @ManyToOne(optional = true, fetch=FetchType.LAZY) @JoinColumn(name = "lastmodifiedby_id", nullable = false) private AppUser modifiedBy; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/domain/FloatingRateRepository.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/domain/FloatingRateRepository.java index af5580a4c..8f4b93f95 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/domain/FloatingRateRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/domain/FloatingRateRepository.java @@ -28,14 +28,14 @@ public interface FloatingRateRepository extends JpaRepository, JpaSpecificationExecutor { - @Query("from FloatingRate floatingRate where floatingRate.isBaseLendingRate = 1 and floatingRate.isActive = 1") + @Query("select floatingRate from FloatingRate floatingRate where floatingRate.isBaseLendingRate = true and floatingRate.isActive = true") FloatingRate retrieveBaseLendingRate(); - @Query("from FloatingRate floatingRate " + + @Query("select floatingRate from FloatingRate floatingRate " + " inner join floatingRate.floatingRatePeriods as periods" + - " where floatingRate.isActive = 1 " + - " and periods.isActive = 1 " + - " and periods.isDifferentialToBaseLendingRate = 1") + " where floatingRate.isActive = true " + + " and periods.isActive = true " + + " and periods.isDifferentialToBaseLendingRate = true") Collection retrieveFloatingRatesLinkedToBLR(); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/service/FloatingRateWritePlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/service/FloatingRateWritePlatformServiceImpl.java index 1e372f250..78e70cc83 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/service/FloatingRateWritePlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/floatingrates/service/FloatingRateWritePlatformServiceImpl.java @@ -20,6 +20,9 @@ package org.apache.fineract.portfolio.floatingrates.service; import java.util.Map; +import javax.persistence.PersistenceException; + +import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder; @@ -70,8 +73,12 @@ public class FloatingRateWritePlatformServiceImpl implements .withEntityId(newFloatingRate.getId()) // .build(); } catch (final DataIntegrityViolationException dve) { - handleDataIntegrityIssues(command, dve); + handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -97,14 +104,17 @@ public class FloatingRateWritePlatformServiceImpl implements .with(changes) // .build(); } catch (final DataIntegrityViolationException dve) { - handleDataIntegrityIssues(command, dve); + handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } - private void handleDataIntegrityIssues(final JsonCommand command, - final DataIntegrityViolationException dve) { - final Throwable realCause = dve.getMostSpecificCause(); + private void handleDataIntegrityIssues(final JsonCommand command, final Throwable realCause, + final Exception dve) { if (realCause.getMessage().contains("unq_name")) { @@ -129,7 +139,7 @@ public class FloatingRateWritePlatformServiceImpl implements } private void logAsErrorUnexpectedDataIntegrityException( - DataIntegrityViolationException dve) { + Exception dve) { logger.error(dve.getMessage(), dve); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/fund/domain/Fund.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/fund/domain/Fund.java index aa6a57918..4b748bc48 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/fund/domain/Fund.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/fund/domain/Fund.java @@ -28,12 +28,12 @@ import javax.persistence.UniqueConstraint; import org.apache.commons.lang.StringUtils; import org.apache.fineract.infrastructure.core.api.JsonCommand; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_fund", uniqueConstraints = { @UniqueConstraint(columnNames = { "name" }, name = "fund_name_org"), @UniqueConstraint(columnNames = { "external_id" }, name = "fund_externalid_org") }) -public class Fund extends AbstractPersistable { +public class Fund extends AbstractPersistableCustom { @Column(name = "name") private String name; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/fund/service/FundWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/fund/service/FundWritePlatformServiceJpaRepositoryImpl.java index ef7217552..f46293936 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/fund/service/FundWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/fund/service/FundWritePlatformServiceJpaRepositoryImpl.java @@ -20,6 +20,9 @@ package org.apache.fineract.portfolio.fund.service; import java.util.Map; +import javax.persistence.PersistenceException; + +import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder; @@ -70,8 +73,12 @@ public class FundWritePlatformServiceJpaRepositoryImpl implements FundWritePlatf return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(fund.getId()).build(); } catch (final DataIntegrityViolationException dve) { - handleFundDataIntegrityIssues(command, dve); + handleFundDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleFundDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -95,8 +102,12 @@ public class FundWritePlatformServiceJpaRepositoryImpl implements FundWritePlatf return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(fund.getId()).with(changes).build(); } catch (final DataIntegrityViolationException dve) { - handleFundDataIntegrityIssues(command, dve); + handleFundDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleFundDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -104,9 +115,7 @@ public class FundWritePlatformServiceJpaRepositoryImpl implements FundWritePlatf * Guaranteed to throw an exception no matter what the data integrity issue * is. */ - private void handleFundDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) { - - final Throwable realCause = dve.getMostSpecificCause(); + private void handleFundDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dve) { if (realCause.getMessage().contains("fund_externalid_org")) { final String externalId = command.stringValueOfParameterNamed("externalId"); throw new PlatformDataIntegrityException("error.msg.fund.duplicate.externalId", "A fund with external id '" + externalId diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/domain/Group.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/domain/Group.java index 602b071c0..c3a14ae7d 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/domain/Group.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/domain/Group.java @@ -49,6 +49,7 @@ import org.apache.fineract.infrastructure.core.data.ApiParameterError; import org.apache.fineract.infrastructure.core.exception.GeneralPlatformDomainRuleException; import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException; import org.apache.fineract.infrastructure.core.service.DateUtils; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.infrastructure.security.service.RandomPasswordGenerator; import org.apache.fineract.organisation.office.domain.Office; import org.apache.fineract.organisation.staff.domain.Staff; @@ -61,11 +62,10 @@ import org.apache.fineract.portfolio.group.exception.GroupNotExistsInCenterExcep import org.apache.fineract.portfolio.group.exception.InvalidGroupStateTransitionException; import org.apache.fineract.useradministration.domain.AppUser; import org.joda.time.LocalDate; -import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @Table(name = "m_group") -public final class Group extends AbstractPersistable { +public final class Group extends AbstractPersistableCustom { @Column(name = "external_id", length = 100, unique = true) private String externalId; @@ -122,7 +122,7 @@ public final class Group extends AbstractPersistable { @Temporal(TemporalType.DATE) private Date closureDate; - @ManyToOne(optional = true) + @ManyToOne(optional = true, fetch=FetchType.LAZY) @JoinColumn(name = "closedon_userid", nullable = true) private AppUser closedBy; @@ -130,7 +130,7 @@ public final class Group extends AbstractPersistable { @Temporal(TemporalType.DATE) private Date submittedOnDate; - @ManyToOne(optional = true) + @ManyToOne(optional = true, fetch=FetchType.LAZY) @JoinColumn(name = "submittedon_userid", nullable = true) private AppUser submittedBy; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/domain/GroupLevel.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/domain/GroupLevel.java index 132fc92b8..093460d1f 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/domain/GroupLevel.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/domain/GroupLevel.java @@ -22,20 +22,20 @@ import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Table; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_group_level") -public class GroupLevel extends AbstractPersistable { +public class GroupLevel extends AbstractPersistableCustom { @Column(name = "parent_id") - private final Long parentId; + private Long parentId; @Column(name = "super_parent", nullable = false) - private final boolean superParent; + private boolean superParent; @Column(name = "level_name", nullable = false, length = 100, unique = true) - private final String levelName; + private String levelName; @Column(name = "recursable", nullable = false) private boolean recursable = false; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/domain/GroupRole.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/domain/GroupRole.java index 137c77a28..d2788262d 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/domain/GroupRole.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/domain/GroupRole.java @@ -29,13 +29,13 @@ import javax.persistence.Table; import org.apache.fineract.infrastructure.codes.domain.CodeValue; import org.apache.fineract.infrastructure.core.api.JsonCommand; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.portfolio.client.domain.Client; import org.apache.fineract.portfolio.group.api.GroupingTypesApiConstants; -import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @Table(name = "m_group_roles") -public class GroupRole extends AbstractPersistable { +public class GroupRole extends AbstractPersistableCustom { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "group_id") diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/service/GroupingTypesWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/service/GroupingTypesWritePlatformServiceJpaRepositoryImpl.java index 1aa8b5c83..0cfc7f955 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/service/GroupingTypesWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/service/GroupingTypesWritePlatformServiceJpaRepositoryImpl.java @@ -26,6 +26,9 @@ import java.util.List; import java.util.Map; import java.util.Set; +import javax.persistence.PersistenceException; + +import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.fineract.commands.domain.CommandWrapper; import org.apache.fineract.commands.service.CommandProcessingService; import org.apache.fineract.commands.service.CommandWrapperBuilder; @@ -225,8 +228,12 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group .build(); } catch (final DataIntegrityViolationException dve) { - handleGroupDataIntegrityIssues(command, dve, groupingType); + handleGroupDataIntegrityIssues(command, dve.getMostSpecificCause(), dve, groupingType); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleGroupDataIntegrityIssues(command, throwable, dve, groupingType); + return CommandProcessingResult.empty(); } } @@ -300,8 +307,12 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group .withEntityId(groupId) // .build(); } catch (final DataIntegrityViolationException dve) { - handleGroupDataIntegrityIssues(command, dve, GroupTypes.GROUP); + handleGroupDataIntegrityIssues(command, dve.getMostSpecificCause(), dve, GroupTypes.GROUP); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleGroupDataIntegrityIssues(command, throwable, dve, GroupTypes.GROUP); + return CommandProcessingResult.empty(); } } @@ -434,8 +445,12 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group .build(); } catch (final DataIntegrityViolationException dve) { - handleGroupDataIntegrityIssues(command, dve, groupingType); + handleGroupDataIntegrityIssues(command, dve.getMostSpecificCause(), dve, groupingType); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleGroupDataIntegrityIssues(command, throwable, dve, groupingType); + return CommandProcessingResult.empty(); } } @@ -697,7 +712,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group * Guaranteed to throw an exception no matter what the data integrity issue * is. */ - private void handleGroupDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve, + private void handleGroupDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dve, final GroupTypes groupLevel) { String levelName = "Invalid"; @@ -712,18 +727,17 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group break; } - final Throwable realCause = dve.getMostSpecificCause(); String errorMessageForUser = null; String errorMessageForMachine = null; - if (realCause.getMessage().contains("external_id")) { + if (realCause.getMessage().contains("'external_id'")) { final String externalId = command.stringValueOfParameterNamed(GroupingTypesApiConstants.externalIdParamName); errorMessageForUser = levelName + " with externalId `" + externalId + "` already exists."; errorMessageForMachine = "error.msg." + levelName.toLowerCase() + ".duplicate.externalId"; throw new PlatformDataIntegrityException(errorMessageForMachine, errorMessageForUser, GroupingTypesApiConstants.externalIdParamName, externalId); - } else if (realCause.getMessage().contains("name")) { + } else if (realCause.getMessage().contains("'name'")) { final String name = command.stringValueOfParameterNamed(GroupingTypesApiConstants.nameParamName); errorMessageForUser = levelName + " with name `" + name + "` already exists."; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/domain/InterestIncentives.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/domain/InterestIncentives.java index 094eadb9b..832044ac6 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/domain/InterestIncentives.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/domain/InterestIncentives.java @@ -29,11 +29,11 @@ import javax.persistence.Table; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_interest_incentives") -public class InterestIncentives extends AbstractPersistable { +public class InterestIncentives extends AbstractPersistableCustom { @ManyToOne @JoinColumn(name = "interest_rate_slab_id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/domain/InterestRateChart.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/domain/InterestRateChart.java index 3537106bb..8e945044e 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/domain/InterestRateChart.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/domain/InterestRateChart.java @@ -54,19 +54,19 @@ import org.apache.fineract.portfolio.interestratechart.InterestRateChartApiConst import org.apache.fineract.portfolio.interestratechart.InterestRateChartSlabApiConstants; import org.apache.fineract.portfolio.savings.SavingsPeriodFrequencyType; import org.joda.time.LocalDate; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import com.google.gson.JsonArray; import com.google.gson.JsonObject; @Entity @Table(name = "m_interest_rate_chart") -public class InterestRateChart extends AbstractPersistable { +public class InterestRateChart extends AbstractPersistableCustom { @Embedded private InterestRateChartFields chartFields; - @OneToMany(mappedBy = "interestRateChart", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) + @OneToMany(mappedBy = "interestRateChart", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER) private Set chartSlabs = new HashSet<>(); protected InterestRateChart() { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/domain/InterestRateChartFields.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/domain/InterestRateChartFields.java index 2b7b7a831..58af84875 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/domain/InterestRateChartFields.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/domain/InterestRateChartFields.java @@ -54,7 +54,7 @@ public class InterestRateChartFields { private Date fromDate; @Temporal(TemporalType.DATE) - @Column(name = "end_date", nullable = false) + @Column(name = "end_date", nullable = true) private Date endDate; @Column(name = "is_primary_grouping_by_amount", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/domain/InterestRateChartSlab.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/domain/InterestRateChartSlab.java index 39ce24d33..d1b14384e 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/domain/InterestRateChartSlab.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/domain/InterestRateChartSlab.java @@ -52,14 +52,14 @@ import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder; import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException; import org.apache.fineract.portfolio.interestratechart.InterestIncentiveApiConstants; import org.apache.fineract.portfolio.interestratechart.InterestRateChartSlabApiConstants; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import com.google.gson.JsonArray; import com.google.gson.JsonObject; @Entity @Table(name = "m_interest_rate_slab") -public class InterestRateChartSlab extends AbstractPersistable { +public class InterestRateChartSlab extends AbstractPersistableCustom { @Embedded private InterestRateChartSlabFields slabFields; @@ -68,7 +68,7 @@ public class InterestRateChartSlab extends AbstractPersistable { @JoinColumn(name = "interest_rate_chart_id", referencedColumnName = "id", nullable = false) private InterestRateChart interestRateChart; - @OneToMany(mappedBy = "interestRateChartSlab", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY) + @OneToMany(mappedBy = "interestRateChartSlab", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER) private Set interestIncentives = new HashSet<>(); protected InterestRateChartSlab() { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/domain/InterestRateChartSlabFields.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/domain/InterestRateChartSlabFields.java index b8c00de93..8a47fb927 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/domain/InterestRateChartSlabFields.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/interestratechart/domain/InterestRateChartSlabFields.java @@ -48,7 +48,7 @@ public class InterestRateChartSlabFields { @Column(name = "description", nullable = true) private String description; - @Column(name = "period_type_enum", nullable = false) + @Column(name = "period_type_enum", nullable = true) private Integer periodType; @Column(name = "from_period") diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java index 5a43e29d2..c1b0f2cce 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java @@ -21,15 +21,44 @@ package org.apache.fineract.portfolio.loanaccount.domain; import java.math.BigDecimal; import java.math.MathContext; import java.math.RoundingMode; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.ListIterator; +import java.util.Locale; +import java.util.Map; +import java.util.Set; -import javax.persistence.*; +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.OneToOne; +import javax.persistence.OrderBy; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.Transient; +import javax.persistence.UniqueConstraint; +import javax.persistence.Version; import org.apache.commons.lang.ObjectUtils; import org.apache.commons.lang.StringUtils; import org.apache.fineract.infrastructure.codes.domain.CodeValue; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.ApiParameterError; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException; import org.apache.fineract.infrastructure.core.serialization.JsonParserHelper; import org.apache.fineract.infrastructure.core.service.DateUtils; @@ -73,10 +102,33 @@ import org.apache.fineract.portfolio.loanaccount.data.HolidayDetailDTO; import org.apache.fineract.portfolio.loanaccount.data.LoanTermVariationsData; import org.apache.fineract.portfolio.loanaccount.data.ScheduleGeneratorDTO; import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.LoanRepaymentScheduleTransactionProcessor; -import org.apache.fineract.portfolio.loanaccount.exception.*; +import org.apache.fineract.portfolio.loanaccount.exception.ExceedingTrancheCountException; +import org.apache.fineract.portfolio.loanaccount.exception.InvalidLoanStateTransitionException; +import org.apache.fineract.portfolio.loanaccount.exception.InvalidLoanTransactionTypeException; +import org.apache.fineract.portfolio.loanaccount.exception.InvalidRefundDateException; +import org.apache.fineract.portfolio.loanaccount.exception.LoanApplicationDateException; +import org.apache.fineract.portfolio.loanaccount.exception.LoanDisbursalException; +import org.apache.fineract.portfolio.loanaccount.exception.LoanForeclosureException; +import org.apache.fineract.portfolio.loanaccount.exception.LoanOfficerAssignmentDateException; +import org.apache.fineract.portfolio.loanaccount.exception.LoanOfficerAssignmentException; +import org.apache.fineract.portfolio.loanaccount.exception.LoanOfficerUnassignmentDateException; +import org.apache.fineract.portfolio.loanaccount.exception.MultiDisbursementDataRequiredException; +import org.apache.fineract.portfolio.loanaccount.exception.UndoLastTrancheDisbursementException; import org.apache.fineract.portfolio.loanaccount.loanschedule.data.LoanScheduleDTO; -import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.*; -import org.apache.fineract.portfolio.loanproduct.domain.*; +import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.AprCalculator; +import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanApplicationTerms; +import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleGenerator; +import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleModel; +import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.LoanScheduleModelPeriod; +import org.apache.fineract.portfolio.loanproduct.domain.AmortizationMethod; +import org.apache.fineract.portfolio.loanproduct.domain.InterestCalculationPeriodMethod; +import org.apache.fineract.portfolio.loanproduct.domain.InterestMethod; +import org.apache.fineract.portfolio.loanproduct.domain.InterestRecalculationCompoundingMethod; +import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct; +import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRelatedDetail; +import org.apache.fineract.portfolio.loanproduct.domain.LoanRescheduleStrategyMethod; +import org.apache.fineract.portfolio.loanproduct.domain.LoanTransactionProcessingStrategy; +import org.apache.fineract.portfolio.loanproduct.domain.RecalculationFrequencyType; import org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations; import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail; import org.apache.fineract.useradministration.domain.AppUser; @@ -85,7 +137,6 @@ import org.joda.time.LocalDate; import org.joda.time.LocalDateTime; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; -import org.springframework.data.jpa.domain.AbstractPersistable; import org.springframework.stereotype.Component; import com.google.gson.JsonArray; @@ -97,7 +148,7 @@ import com.google.gson.JsonPrimitive; @Component @Table(name = "m_loan", uniqueConstraints = { @UniqueConstraint(columnNames = { "account_no" }, name = "loan_account_no_UNIQUE"), @UniqueConstraint(columnNames = { "external_id" }, name = "loan_externalid_UNIQUE") }) -public class Loan extends AbstractPersistable { +public class Loan extends AbstractPersistableCustom { /** Disable optimistic locking till batch jobs failures can be fixed **/ @Version @@ -259,11 +310,11 @@ public class Loan extends AbstractPersistable { @OrderBy(value = "installmentNumber") @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true, fetch=FetchType.LAZY) - private final List repaymentScheduleInstallments = new ArrayList<>(); + private List repaymentScheduleInstallments = new ArrayList<>(); @OrderBy(value = "dateOf, id") @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true, fetch=FetchType.LAZY) - private final List loanTransactions = new ArrayList<>(); + private List loanTransactions = new ArrayList<>(); @Embedded private LoanSummary summary; @@ -287,7 +338,7 @@ public class Loan extends AbstractPersistable { @Column(name = "fixed_emi_amount", scale = 6, precision = 19, nullable = true) private BigDecimal fixedEmiAmount; - @Column(name = "max_outstanding_loan_balance", scale = 6, precision = 19, nullable = false) + @Column(name = "max_outstanding_loan_balance", scale = 6, precision = 19, nullable = true) private BigDecimal maxOutstandingLoanBalance; @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true, fetch=FetchType.LAZY) @@ -296,7 +347,7 @@ public class Loan extends AbstractPersistable { @OrderBy(value = "termApplicableFrom, id") @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true, fetch=FetchType.LAZY) - private final List loanTermVariations = new ArrayList<>(); + private List loanTermVariations = new ArrayList<>(); @Column(name = "total_recovered_derived", scale = 6, precision = 19) private BigDecimal totalRecovered; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanCharge.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanCharge.java index 0189ee4df..05de5fa35 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanCharge.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanCharge.java @@ -41,8 +41,8 @@ import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; -import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.fineract.infrastructure.core.api.JsonCommand; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency; import org.apache.fineract.organisation.monetary.domain.Money; import org.apache.fineract.organisation.monetary.domain.MoneyHelper; @@ -54,11 +54,10 @@ import org.apache.fineract.portfolio.charge.exception.LoanChargeWithoutMandatory import org.apache.fineract.portfolio.loanaccount.command.LoanChargeCommand; import org.apache.fineract.portfolio.loanaccount.data.LoanChargePaidDetail; import org.joda.time.LocalDate; -import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @Table(name = "m_loan_charge") -public class LoanCharge extends AbstractPersistable { +public class LoanCharge extends AbstractPersistableCustom { @ManyToOne(optional = false) @JoinColumn(name = "loan_id", referencedColumnName = "id", nullable = false) @@ -121,15 +120,15 @@ public class LoanCharge extends AbstractPersistable { private BigDecimal maxCap; @OneToMany(cascade = CascadeType.ALL, mappedBy = "loancharge", orphanRemoval = true, fetch=FetchType.EAGER) - private final Set loanInstallmentCharge = new HashSet<>(); + private Set loanInstallmentCharge = new HashSet<>(); @Column(name = "is_active", nullable = false) private boolean active = true; - @OneToOne(mappedBy = "loancharge", cascade = CascadeType.ALL, optional = true, orphanRemoval = true, fetch = FetchType.LAZY) + @OneToOne(mappedBy = "loancharge", cascade = CascadeType.ALL, optional = true, orphanRemoval = true, fetch = FetchType.EAGER) private LoanOverdueInstallmentCharge overdueInstallmentCharge; - @OneToOne(mappedBy = "loancharge", cascade = CascadeType.ALL, optional = true, orphanRemoval = true, fetch = FetchType.LAZY) + @OneToOne(mappedBy = "loancharge", cascade = CascadeType.ALL, optional = true, orphanRemoval = true, fetch = FetchType.EAGER) private LoanTrancheDisbursementCharge loanTrancheDisbursementCharge; public static LoanCharge createNewFromJson(final Loan loan, final Charge chargeDefinition, final JsonCommand command) { @@ -500,7 +499,7 @@ public class LoanCharge extends AbstractPersistable { for (final LoanInstallmentCharge chargePerInstallment : this.loanInstallmentCharge) { if (index == loanChargePerInstallmentArray.length) { remove.add(chargePerInstallment); - chargePerInstallment.updateInstallment(null); + //chargePerInstallment.updateInstallment(null); } else { chargePerInstallment.copyFrom(loanChargePerInstallmentArray[index++]); } @@ -757,7 +756,7 @@ public class LoanCharge extends AbstractPersistable { return this.charge; } - @Override + /*@Override public boolean equals(final Object obj) { if (obj == null) { return false; } if (obj == this) { return true; } @@ -774,12 +773,12 @@ public class LoanCharge extends AbstractPersistable { @Override public int hashCode() { return 1; - /* + * return new HashCodeBuilder(3, 5) // .append(getId()) // * .append(this.charge.getId()) // * .append(this.amount).append(getDueLocalDate()) // .toHashCode(); - */ - } + + }*/ public ChargePaymentMode getChargePaymentMode() { return ChargePaymentMode.fromInt(this.chargePaymentMode); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanChargePaidBy.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanChargePaidBy.java index c2fbfefec..9328e9ee6 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanChargePaidBy.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanChargePaidBy.java @@ -27,11 +27,11 @@ import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_loan_charge_paid_by") -public class LoanChargePaidBy extends AbstractPersistable { +public class LoanChargePaidBy extends AbstractPersistableCustom { @ManyToOne @JoinColumn(name = "loan_transaction_id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanDisbursementDetails.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanDisbursementDetails.java index 0fba38a48..ef70a18d5 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanDisbursementDetails.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanDisbursementDetails.java @@ -29,13 +29,13 @@ import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.portfolio.loanaccount.data.DisbursementData; import org.joda.time.LocalDate; -import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @Table(name = "m_loan_disbursement_detail") -public class LoanDisbursementDetails extends AbstractPersistable { +public class LoanDisbursementDetails extends AbstractPersistableCustom { @ManyToOne @JoinColumn(name = "loan_id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanInstallmentCharge.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanInstallmentCharge.java index f1f8c4e6e..22e23f56b 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanInstallmentCharge.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanInstallmentCharge.java @@ -26,13 +26,13 @@ import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency; import org.apache.fineract.organisation.monetary.domain.Money; -import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @Table(name = "m_loan_installment_charge") -public class LoanInstallmentCharge extends AbstractPersistable { +public class LoanInstallmentCharge extends AbstractPersistableCustom { @ManyToOne(optional = false) @JoinColumn(name = "loan_charge_id", referencedColumnName = "id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanInterestRecalcualtionAdditionalDetails.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanInterestRecalcualtionAdditionalDetails.java index f37476025..246af1e9f 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanInterestRecalcualtionAdditionalDetails.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanInterestRecalcualtionAdditionalDetails.java @@ -27,12 +27,12 @@ import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.joda.time.LocalDate; -import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @Table(name = "m_loan_interest_recalculation_additional_details") -public class LoanInterestRecalcualtionAdditionalDetails extends AbstractPersistable { +public class LoanInterestRecalcualtionAdditionalDetails extends AbstractPersistableCustom { @Temporal(TemporalType.DATE) @Column(name = "effective_date") diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanInterestRecalculationDetails.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanInterestRecalculationDetails.java index a56c004b1..b5757d57d 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanInterestRecalculationDetails.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanInterestRecalculationDetails.java @@ -24,11 +24,11 @@ import javax.persistence.JoinColumn; import javax.persistence.OneToOne; import javax.persistence.Table; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.portfolio.loanproduct.domain.InterestRecalculationCompoundingMethod; import org.apache.fineract.portfolio.loanproduct.domain.LoanProductInterestRecalculationDetails; import org.apache.fineract.portfolio.loanproduct.domain.LoanRescheduleStrategyMethod; import org.apache.fineract.portfolio.loanproduct.domain.RecalculationFrequencyType; -import org.springframework.data.jpa.domain.AbstractPersistable; /** * Entity for holding interest recalculation setting, details will be copied @@ -39,7 +39,7 @@ import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @Table(name = "m_loan_recalculation_details") -public class LoanInterestRecalculationDetails extends AbstractPersistable { +public class LoanInterestRecalculationDetails extends AbstractPersistableCustom { @OneToOne @JoinColumn(name = "loan_id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanOverdueInstallmentCharge.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanOverdueInstallmentCharge.java index e1a932696..7385489c0 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanOverdueInstallmentCharge.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanOverdueInstallmentCharge.java @@ -24,11 +24,11 @@ import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_loan_overdue_installment_charge") -public class LoanOverdueInstallmentCharge extends AbstractPersistable { +public class LoanOverdueInstallmentCharge extends AbstractPersistableCustom { @ManyToOne(optional = false) @JoinColumn(name = "loan_charge_id", referencedColumnName = "id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallment.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallment.java index c31d1ecb3..81eff34fa 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallment.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallment.java @@ -46,7 +46,7 @@ import org.joda.time.LocalDate; public final class LoanRepaymentScheduleInstallment extends AbstractAuditableCustom { @ManyToOne(optional = false) - @JoinColumn(name = "loan_id") + @JoinColumn(name = "loan_id", referencedColumnName="id") private Loan loan; @Column(name = "installment", nullable = false) @@ -133,6 +133,7 @@ public final class LoanRepaymentScheduleInstallment extends AbstractAuditableCus @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch=FetchType.EAGER) @JoinColumn(name = "loan_repayment_schedule_id", referencedColumnName = "id", nullable = false) private Set loanCompoundingDetails = new HashSet<>(); + protected LoanRepaymentScheduleInstallment() { this.installmentNumber = null; this.fromDate = null; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepository.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepository.java index 9292ace7e..fe17368b1 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepository.java @@ -29,10 +29,10 @@ import org.springframework.data.repository.query.Param; public interface LoanRepository extends JpaRepository, JpaSpecificationExecutor { - public static final String FIND_GROUP_LOANS_DISBURSED_AFTER = "from Loan l where l.actualDisbursementDate > :disbursementDate and " + public static final String FIND_GROUP_LOANS_DISBURSED_AFTER = "select l from Loan l where l.actualDisbursementDate > :disbursementDate and " + "l.group.id = :groupId and l.loanType = :loanType order by l.actualDisbursementDate"; - public static final String FIND_CLIENT_OR_JLG_LOANS_DISBURSED_AFTER = "from Loan l where l.actualDisbursementDate > :disbursementDate and " + public static final String FIND_CLIENT_OR_JLG_LOANS_DISBURSED_AFTER = "select l from Loan l where l.actualDisbursementDate > :disbursementDate and " + "l.client.id = :clientId order by l.actualDisbursementDate"; public static final String FIND_MAX_GROUP_LOAN_COUNTER_QUERY = "Select MAX(l.loanCounter) from Loan l where l.group.id = :groupId " @@ -47,16 +47,16 @@ public interface LoanRepository extends JpaRepository, JpaSpecificat public static final String FIND_MAX_CLIENT_OR_JLG_LOAN_PRODUCT_COUNTER_QUERY = "Select MAX(l.loanProductCounter) from Loan l where " + "l.client.id = :clientId and l.loanProduct.id = :productId"; - public static final String FIND_GROUP_LOANS_TO_UPDATE = "from Loan l where l.loanCounter > :loanCounter and " + public static final String FIND_GROUP_LOANS_TO_UPDATE = "select l from Loan l where l.loanCounter > :loanCounter and " + "l.group.id = :groupId and l.loanType = :groupLoanType order by l.loanCounter"; - public static final String FIND_CLIENT_OR_JLG_LOANS_TO_UPDATE = "from Loan l where l.loanCounter > :loanCounter and " + public static final String FIND_CLIENT_OR_JLG_LOANS_TO_UPDATE = "select l from Loan l where l.loanCounter > :loanCounter and " + "l.client.id = :clientId order by l.loanCounter"; - public static final String FIND_GROUP_LOANS_TO_UPDATE_LOANPRODUCT_COUNTER = "from Loan l where l.loanProductCounter > :loanProductCounter" + public static final String FIND_GROUP_LOANS_TO_UPDATE_LOANPRODUCT_COUNTER = "select l from Loan l where l.loanProductCounter > :loanProductCounter" + " and l.group.id = :groupId and l.loanType = :groupLoanType and l.loanCounter is NULL order by l.loanProductCounter"; - public static final String FIND_CLIENT_LOANS_TO_UPDATE_LOANPRODUCT_COUNTER = "from Loan l where l.loanProductCounter > :loanProductCounter" + public static final String FIND_CLIENT_LOANS_TO_UPDATE_LOANPRODUCT_COUNTER = "select l from Loan l where l.loanProductCounter > :loanProductCounter" + " and l.client.id = :clientId and l.loanCounter is NULL order by l.loanProductCounter"; public static final String FIND_ACTIVE_LOANS_PRODUCT_IDS_BY_CLIENT = "Select loan.loanProduct.id from Loan loan where " @@ -65,13 +65,13 @@ public interface LoanRepository extends JpaRepository, JpaSpecificat public static final String FIND_ACTIVE_LOANS_PRODUCT_IDS_BY_GROUP = "Select loan.loanProduct.id from Loan loan where " + "loan.group.id = :groupId and loan.loanStatus = :loanStatus and loan.client.id is NULL group by loan.loanProduct.id"; - public static final String DOES_CLIENT_HAVE_NON_CLOSED_LOANS = "select case when (count (loan) > 0) then true else false end from Loan loan where loan.client.id = :clientId and loan.loanStatus in (100,200,300,303,304,700)"; + public static final String DOES_CLIENT_HAVE_NON_CLOSED_LOANS = "select case when (count (loan) > 0) then 'true' else 'false' end from Loan loan where loan.client.id = :clientId and loan.loanStatus in (100,200,300,303,304,700)"; - public static final String DOES_PRODUCT_HAVE_NON_CLOSED_LOANS = "select case when (count (loan) > 0) then true else false end from Loan loan where loan.loanProduct.id = :productId and loan.loanStatus in (100,200,300,303,304,700)"; + public static final String DOES_PRODUCT_HAVE_NON_CLOSED_LOANS = "select case when (count (loan) > 0) then 'true' else 'false' end from Loan loan where loan.loanProduct.id = :productId and loan.loanStatus in (100,200,300,303,304,700)"; - public static final String FIND_BY_ACCOUNT_NUMBER = "from Loan loan where loan.accountNumber = :accountNumber and loan.loanStatus in (100,200,300,303,304)"; + public static final String FIND_BY_ACCOUNT_NUMBER = "select loan from Loan loan where loan.accountNumber = :accountNumber and loan.loanStatus in (100,200,300,303,304)"; - public static final String FIND_NON_CLOSED_LOAN_THAT_BELONGS_TO_CLIENT = "from Loan loan where loan.id = :loanId and loan.loanStatus = 300 and loan.client.id = :clientId"; + public static final String FIND_NON_CLOSED_LOAN_THAT_BELONGS_TO_CLIENT = "select loan from Loan loan where loan.id = :loanId and loan.loanStatus = 300 and loan.client.id = :clientId"; @Query(FIND_GROUP_LOANS_DISBURSED_AFTER) List getGroupLoansDisbursedAfter(@Param("disbursementDate") Date disbursementDate, @Param("groupId") Long groupId, @@ -108,31 +108,31 @@ public interface LoanRepository extends JpaRepository, JpaSpecificat List getClientLoansToUpdateLoanProductCounter(@Param("loanProductCounter") Integer loanProductCounter, @Param("clientId") Long clientId); - @Query("from Loan loan where loan.client.id = :clientId and loan.group.id = :groupId") + @Query("select loan from Loan loan where loan.client.id = :clientId and loan.group.id = :groupId") List findByClientIdAndGroupId(@Param("clientId") Long clientId, @Param("groupId") Long groupId); - @Query("from Loan loan where loan.client.id = :clientId and loan.group.id = :groupId and loan.loanStatus IN :loanStatuses") + @Query("select loan from Loan loan where loan.client.id = :clientId and loan.group.id = :groupId and loan.loanStatus IN :loanStatuses") List findByClientIdAndGroupIdAndLoanStatus(@Param("clientId") Long clientId, @Param("groupId") Long groupId, @Param("loanStatuses") Collection loanStatuses); - @Query("from Loan loan where loan.client.id = :clientId") + @Query("select loan from Loan loan where loan.client.id = :clientId") List findLoanByClientId(@Param("clientId") Long clientId); - @Query("from Loan loan where loan.group.id = :groupId and loan.client.id is null") + @Query("select loan from Loan loan where loan.group.id = :groupId and loan.client.id is null") List findByGroupId(@Param("groupId") Long groupId); - @Query("from Loan loan where loan.id IN :ids and loan.loanStatus IN :loanStatuses and loan.loanType IN :loanTypes") + @Query("select loan from Loan loan where loan.id IN :ids and loan.loanStatus IN :loanStatuses and loan.loanType IN :loanTypes") List findByIdsAndLoanStatusAndLoanType(@Param("ids") Collection ids, @Param("loanStatuses") Collection loanStatuses, @Param("loanTypes") Collection loanTypes); @Query("select loan.id from Loan loan where loan.actualDisbursementDate > :disbursalDate order by loan.actualDisbursementDate") List getLoansDisbursedAfter(@Param("disbursalDate") Date disbursalDate); - @Query("from Loan loan where loan.client.office.id IN :officeIds and loan.loanStatus IN :loanStatuses") + @Query("select loan from Loan loan where loan.client.office.id IN :officeIds and loan.loanStatus IN :loanStatuses") List findByClientOfficeIdsAndLoanStatus(@Param("officeIds") Collection officeIds, @Param("loanStatuses") Collection loanStatuses); - @Query("from Loan loan where loan.group.office.id IN :officeIds and loan.loanStatus IN :loanStatuses") + @Query("select loan from Loan loan where loan.group.office.id IN :officeIds and loan.loanStatus IN :loanStatuses") List findByGroupOfficeIdsAndLoanStatus(@Param("officeIds") Collection officeIds, @Param("loanStatuses") Collection loanStatuses); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepositoryWrapper.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepositoryWrapper.java index 9a3252360..c692bb390 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepositoryWrapper.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepositoryWrapper.java @@ -72,6 +72,7 @@ public class LoanRepositoryWrapper { return this.repository.saveAndFlush(loan) ; } + @Transactional public Loan save(final Loan loan) { return this.repository.save(loan) ; } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRescheduleRequestToTermVariationMapping.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRescheduleRequestToTermVariationMapping.java index af9a8e24e..e6976a84d 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRescheduleRequestToTermVariationMapping.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRescheduleRequestToTermVariationMapping.java @@ -23,11 +23,12 @@ import javax.persistence.Entity; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; -import org.springframework.data.jpa.domain.AbstractPersistable; + +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name="m_loan_reschedule_request_term_variations_mapping") -public class LoanRescheduleRequestToTermVariationMapping extends AbstractPersistable { +public class LoanRescheduleRequestToTermVariationMapping extends AbstractPersistableCustom { @ManyToOne(optional = false, cascade = CascadeType.PERSIST) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTermVariations.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTermVariations.java index 6dbadad9f..6171a02ff 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTermVariations.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTermVariations.java @@ -30,15 +30,16 @@ import javax.persistence.OneToOne; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; + import org.apache.fineract.infrastructure.core.data.EnumOptionData; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.portfolio.loanaccount.data.LoanTermVariationsData; import org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations; import org.joda.time.LocalDate; -import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @Table(name = "m_loan_term_variations") -public class LoanTermVariations extends AbstractPersistable { +public class LoanTermVariations extends AbstractPersistableCustom { @ManyToOne(optional = false) @JoinColumn(name = "loan_id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTopupDetails.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTopupDetails.java index 106654e7b..1708bb3ee 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTopupDetails.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTopupDetails.java @@ -18,16 +18,19 @@ */ package org.apache.fineract.portfolio.loanaccount.domain; -import org.apache.fineract.portfolio.account.domain.AccountTransferDetails; -import org.springframework.data.jpa.domain.AbstractPersistable; -import org.springframework.stereotype.Component; - -import javax.persistence.*; import java.math.BigDecimal; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.OneToOne; +import javax.persistence.Table; + +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; + @Entity @Table(name = "m_loan_topup") -public class LoanTopupDetails extends AbstractPersistable { +public class LoanTopupDetails extends AbstractPersistableCustom { @OneToOne @JoinColumn(name = "loan_id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTrancheCharge.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTrancheCharge.java index 35860c86c..5c6a8a630 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTrancheCharge.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTrancheCharge.java @@ -24,12 +24,12 @@ import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.portfolio.charge.domain.Charge; -import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @Table(name = "m_loan_tranche_charges") -public class LoanTrancheCharge extends AbstractPersistable { +public class LoanTrancheCharge extends AbstractPersistableCustom { @ManyToOne(cascade = CascadeType.ALL, optional = false) @JoinColumn(name = "loan_id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTrancheDisbursementCharge.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTrancheDisbursementCharge.java index fa65d0dec..d2258cef0 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTrancheDisbursementCharge.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTrancheDisbursementCharge.java @@ -23,11 +23,12 @@ import javax.persistence.Entity; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; -import org.springframework.data.jpa.domain.AbstractPersistable; + +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name="m_loan_tranche_disbursement_charge") -public class LoanTrancheDisbursementCharge extends AbstractPersistable { +public class LoanTrancheDisbursementCharge extends AbstractPersistableCustom { @ManyToOne @JoinColumn(name = "loan_charge_id", referencedColumnName = "id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransaction.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransaction.java index 7b16a5c54..3dc1cb728 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransaction.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransaction.java @@ -40,6 +40,7 @@ import javax.persistence.Temporal; import javax.persistence.TemporalType; import javax.persistence.UniqueConstraint; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.infrastructure.core.service.DateUtils; import org.apache.fineract.organisation.monetary.data.CurrencyData; import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency; @@ -54,7 +55,6 @@ import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail; import org.apache.fineract.useradministration.domain.AppUser; import org.joda.time.LocalDate; import org.joda.time.LocalDateTime; -import org.springframework.data.jpa.domain.AbstractPersistable; /** * All monetary transactions against a loan are modelled through this entity. @@ -62,7 +62,7 @@ import org.springframework.data.jpa.domain.AbstractPersistable; */ @Entity @Table(name = "m_loan_transaction", uniqueConstraints = { @UniqueConstraint(columnNames = { "external_id" }, name = "external_id_UNIQUE") }) -public final class LoanTransaction extends AbstractPersistable { +public class LoanTransaction extends AbstractPersistableCustom { @ManyToOne(optional = false) @JoinColumn(name = "loan_id", nullable = false) @@ -77,15 +77,15 @@ public final class LoanTransaction extends AbstractPersistable { private PaymentDetail paymentDetail; @Column(name = "transaction_type_enum", nullable = false) - private final Integer typeOf; + private Integer typeOf; @Temporal(TemporalType.DATE) @Column(name = "transaction_date", nullable = false) - private final Date dateOf; + private Date dateOf; @Temporal(TemporalType.DATE) @Column(name = "submitted_on_date", nullable = false) - private final Date submittedOnDate; + private Date submittedOnDate; @Column(name = "amount", scale = 6, precision = 19, nullable = false) private BigDecimal amount; @@ -118,9 +118,9 @@ public final class LoanTransaction extends AbstractPersistable { @Column(name = "created_date", nullable = false) private Date createdDate; - @ManyToOne + @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name = "appuser_id", nullable = true) - private final AppUser appUser; + private AppUser appUser; @OneToMany(cascade = CascadeType.ALL, mappedBy = "loanTransaction", orphanRemoval = true, fetch=FetchType.EAGER) private Set loanChargesPaid = new HashSet<>(); @@ -136,12 +136,12 @@ public final class LoanTransaction extends AbstractPersistable { private Set loanTransactionToRepaymentScheduleMappings = new HashSet<>(); protected LoanTransaction() { - this.loan = null; + /* this.loan = null; this.dateOf = null; this.typeOf = null; this.submittedOnDate = DateUtils.getDateOfTenant(); this.createdDate = new Date(); - this.appUser = null; + this.appUser = null;*/ } public static LoanTransaction incomePosting(final Loan loan, final Office office, final Date dateOf, final BigDecimal amount, diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransactionToRepaymentScheduleMapping.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransactionToRepaymentScheduleMapping.java index 78d19cc21..7e4685c51 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransactionToRepaymentScheduleMapping.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransactionToRepaymentScheduleMapping.java @@ -27,13 +27,13 @@ import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency; import org.apache.fineract.organisation.monetary.domain.Money; -import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @Table(name = "m_loan_transaction_repayment_schedule_mapping") -public class LoanTransactionToRepaymentScheduleMapping extends AbstractPersistable { +public class LoanTransactionToRepaymentScheduleMapping extends AbstractPersistableCustom { @ManyToOne(optional = false, cascade = CascadeType.PERSIST) @JoinColumn(name = "loan_repayment_schedule_id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/domain/Guarantor.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/domain/Guarantor.java index b52e4e793..730f60af9 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/domain/Guarantor.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/domain/Guarantor.java @@ -40,11 +40,11 @@ import org.apache.fineract.infrastructure.codes.domain.CodeValue; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.portfolio.loanaccount.domain.Loan; import org.apache.fineract.portfolio.loanaccount.guarantor.GuarantorConstants.GUARANTOR_JSON_INPUT_PARAMS; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_guarantor") -public class Guarantor extends AbstractPersistable { +public class Guarantor extends AbstractPersistableCustom { @ManyToOne @JoinColumn(name = "loan_id", nullable = false) @@ -101,7 +101,7 @@ public class Guarantor extends AbstractPersistable { private boolean active; @OneToMany(cascade = CascadeType.ALL, mappedBy = "guarantor", orphanRemoval = true, fetch=FetchType.EAGER) - private final List guarantorFundDetails = new ArrayList<>(); + private List guarantorFundDetails = new ArrayList<>(); protected Guarantor() { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/domain/GuarantorFundingDetails.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/domain/GuarantorFundingDetails.java index 0179cb217..993c0d70c 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/domain/GuarantorFundingDetails.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/domain/GuarantorFundingDetails.java @@ -34,11 +34,11 @@ import javax.persistence.Table; import org.apache.fineract.portfolio.account.domain.AccountAssociations; import org.apache.fineract.portfolio.loanaccount.domain.Loan; import org.apache.fineract.portfolio.savings.domain.SavingsAccount; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_guarantor_funding_details") -public class GuarantorFundingDetails extends AbstractPersistable { +public class GuarantorFundingDetails extends AbstractPersistableCustom { @ManyToOne @JoinColumn(name = "guarantor_id", nullable = false) @@ -64,7 +64,7 @@ public class GuarantorFundingDetails extends AbstractPersistable { private BigDecimal amountTransfered; @OneToMany(cascade = CascadeType.ALL, mappedBy = "guarantorFundingDetails", orphanRemoval = true, fetch=FetchType.EAGER) - private final List guarantorFundingTransactions = new ArrayList<>(); + private List guarantorFundingTransactions = new ArrayList<>(); protected GuarantorFundingDetails() {} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/domain/GuarantorFundingTransaction.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/domain/GuarantorFundingTransaction.java index aa12fb805..2c6edb12e 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/domain/GuarantorFundingTransaction.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/domain/GuarantorFundingTransaction.java @@ -29,11 +29,11 @@ import javax.persistence.Table; import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction; import org.apache.fineract.portfolio.savings.domain.DepositAccountOnHoldTransaction; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_guarantor_transaction") -public class GuarantorFundingTransaction extends AbstractPersistable { +public class GuarantorFundingTransaction extends AbstractPersistableCustom { @ManyToOne @JoinColumn(name = "guarantor_fund_detail_id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/domain/GuarantorFundingTransactionRepository.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/domain/GuarantorFundingTransactionRepository.java index adb75235a..4e4f7a020 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/domain/GuarantorFundingTransactionRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/domain/GuarantorFundingTransactionRepository.java @@ -28,7 +28,7 @@ import org.springframework.data.repository.query.Param; public interface GuarantorFundingTransactionRepository extends JpaRepository, JpaSpecificationExecutor { - @Query("from GuarantorFundingTransaction ft where ft.loanTransaction.id in (:loanTransactions)") + @Query("select ft from GuarantorFundingTransaction ft where ft.loanTransaction.id in (:loanTransactions)") List fetchGuarantorFundingTransactions(@Param("loanTransactions") List loanTransactions); } \ No newline at end of file diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractLoanScheduleGenerator.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractLoanScheduleGenerator.java index d249e356c..bf4a64bf1 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractLoanScheduleGenerator.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractLoanScheduleGenerator.java @@ -1373,32 +1373,32 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener params.getActualRepaymentDate(), applicableVariations); Money interest = principalInterestForThisPeriod.interest(); totalInterest = totalInterest.plus(interest); - - Money uncompounded = params.getUnCompoundedAmount(); - Money compounded = uncompounded.zero(); - for (Map.Entry mapEntry : params.getCompoundingMap().entrySet()) { - if (mapEntry.getKey().isAfter(params.getPeriodStartDate())) { - compounded = compounded.plus(mapEntry.getValue()); - } - } - if (compounded.isGreaterThanZero() && startDate.isEqual(additionalPeriodsStartDate)) { - params.setCompoundedInLastInstallment(uncompoundedFromLastInstallment);// uncompounded in last installment - additionalPeriodsStartDate = additionalPeriodsStartDate.plusDays(1); - } - Money compoundedForThisPeriod = compounded.minus(uncompounded); - Money uncompoundedForThisPeriod = interest.minus(compoundedForThisPeriod); - params.setUnCompoundedAmount(uncompoundedForThisPeriod); - LocalDate compoundingDate = params.getPeriodStartDate(); - if (loanApplicationTerms.allowCompoundingOnEod()) { - compoundingDate = compoundingDate.minusDays(1); - } - compoundingDate = getNextCompoundScheduleDate(compoundingDate, loanApplicationTerms, holidayDetailDTO); - if(compoundingDate.isEqual(params.getActualRepaymentDate())){ - params.getCompoundingMap().put(compoundingDate, uncompoundedForThisPeriod); - params.setUnCompoundedAmount(uncompoundedForThisPeriod.zero()); - } - + if(loanApplicationTerms.getInterestRecalculationCompoundingMethod().isCompoundingEnabled()) { + Money uncompounded = params.getUnCompoundedAmount(); + Money compounded = uncompounded.zero(); + for (Map.Entry mapEntry : params.getCompoundingMap().entrySet()) { + if (mapEntry.getKey().isAfter(params.getPeriodStartDate())) { + compounded = compounded.plus(mapEntry.getValue()); + } + } + if (compounded.isGreaterThanZero() && startDate.isEqual(additionalPeriodsStartDate)) { + params.setCompoundedInLastInstallment(uncompoundedFromLastInstallment);// uncompounded in last installment + additionalPeriodsStartDate = additionalPeriodsStartDate.plusDays(1); + } + Money compoundedForThisPeriod = compounded.minus(uncompounded); + Money uncompoundedForThisPeriod = interest.minus(compoundedForThisPeriod); + params.setUnCompoundedAmount(uncompoundedForThisPeriod); + LocalDate compoundingDate = params.getPeriodStartDate(); + if (loanApplicationTerms.allowCompoundingOnEod()) { + compoundingDate = compoundingDate.minusDays(1); + } + compoundingDate = getNextCompoundScheduleDate(compoundingDate, loanApplicationTerms, holidayDetailDTO); + if(compoundingDate.isEqual(params.getActualRepaymentDate())){ + params.getCompoundingMap().put(compoundingDate, uncompoundedForThisPeriod); + params.setUnCompoundedAmount(uncompoundedForThisPeriod.zero()); + } + } } params.setPeriodStartDate(params.getActualRepaymentDate()); } while (params.getActualRepaymentDate().isBefore(currentDate) && !outstanding.isZero()); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanRepaymentScheduleHistory.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanRepaymentScheduleHistory.java index 4f962aa18..baef5c6a3 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanRepaymentScheduleHistory.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanRepaymentScheduleHistory.java @@ -33,11 +33,11 @@ import javax.persistence.TemporalType; import org.apache.fineract.portfolio.loanaccount.domain.Loan; import org.apache.fineract.portfolio.loanaccount.rescheduleloan.domain.LoanRescheduleRequest; import org.apache.fineract.useradministration.domain.AppUser; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_loan_repayment_schedule_history") -public class LoanRepaymentScheduleHistory extends AbstractPersistable { +public class LoanRepaymentScheduleHistory extends AbstractPersistableCustom { @ManyToOne(optional = false) @JoinColumn(name = "loan_id") diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/domain/LoanRescheduleRequest.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/domain/LoanRescheduleRequest.java index 8a0a8441c..188d20af4 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/domain/LoanRescheduleRequest.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/domain/LoanRescheduleRequest.java @@ -41,11 +41,11 @@ import org.apache.fineract.portfolio.loanaccount.domain.LoanStatus; import org.apache.fineract.portfolio.loanaccount.domain.LoanTermVariations; import org.apache.fineract.useradministration.domain.AppUser; import org.joda.time.LocalDate; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_loan_reschedule_request") -public class LoanRescheduleRequest extends AbstractPersistable { +public class LoanRescheduleRequest extends AbstractPersistableCustom { @ManyToOne @JoinColumn(name = "loan_id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java index 70702186d..b697797bf 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java @@ -26,7 +26,11 @@ import java.util.List; import java.util.Map; import java.util.Set; +import javax.persistence.EntityExistsException; +import javax.persistence.PersistenceException; + import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.fineract.infrastructure.accountnumberformat.domain.AccountNumberFormat; import org.apache.fineract.infrastructure.accountnumberformat.domain.AccountNumberFormatRepositoryWrapper; import org.apache.fineract.infrastructure.accountnumberformat.domain.EntityAccountType; @@ -413,8 +417,12 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa .withLoanId(newLoanApplication.getId()) // .build(); } catch (final DataIntegrityViolationException dve) { - handleDataIntegrityIssues(command, dve); + handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch(final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -989,8 +997,12 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa .withLoanId(existingLoanApplication.getId()) // .with(changes).build(); } catch (final DataIntegrityViolationException dve) { - handleDataIntegrityIssues(command, dve); + handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -998,16 +1010,14 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa * Guaranteed to throw an exception no matter what the data integrity issue * is. */ - private void handleDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) { - - final Throwable realCause = dve.getMostSpecificCause(); - if (realCause.getMessage().contains("loan_account_no_UNIQUE")) { + private void handleDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dve) { + + if (realCause.getMessage().contains("loan_account_no_UNIQUE") || realCause.getCause().getMessage().contains("loan_account_no_UNIQUE")) { final String accountNo = command.stringValueOfParameterNamed("accountNo"); throw new PlatformDataIntegrityException("error.msg.loan.duplicate.accountNo", "Loan with accountNo `" + accountNo + "` already exists", "accountNo", accountNo); - } else if (realCause.getMessage().contains("loan_externalid_UNIQUE")) { - + } else if (realCause.getMessage().contains("loan_externalid_UNIQUE") || realCause.getCause().getMessage().contains("loan_externalid_UNIQUE")) { final String externalId = command.stringValueOfParameterNamed("externalId"); throw new PlatformDataIntegrityException("error.msg.loan.duplicate.externalId", "Loan with externalId `" + externalId + "` already exists", "externalId", externalId); @@ -1017,7 +1027,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa throw new PlatformDataIntegrityException("error.msg.unknown.data.integrity.issue", "Unknown data integrity issue with resource."); } - private void logAsErrorUnexpectedDataIntegrityException(final DataIntegrityViolationException dve) { + private void logAsErrorUnexpectedDataIntegrityException(final Exception dve) { logger.error(dve.getMessage(), dve); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanArrearsAgingServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanArrearsAgingServiceImpl.java index f1db73960..6a39299d0 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanArrearsAgingServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanArrearsAgingServiceImpl.java @@ -19,7 +19,6 @@ package org.apache.fineract.portfolio.loanaccount.service; import java.math.BigDecimal; -import java.math.BigInteger; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanChargeAssembler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanChargeAssembler.java index 67bd9aa6d..a49bb9758 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanChargeAssembler.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanChargeAssembler.java @@ -204,13 +204,12 @@ public class LoanChargeAssembler { } else { final Long loanChargeId = id; final LoanCharge loanCharge = this.loanChargeRepository.findOne(loanChargeId); - if (disbursementChargeIds.contains(loanChargeId) && loanCharge == null) { - // throw new - // LoanChargeNotFoundException(loanChargeId); - } if (loanCharge != null) { - loanCharge.update(amount, dueDate, numberOfRepayments); - loanCharges.add(loanCharge); + if(!loanCharge.isTrancheDisbursementCharge() + || disbursementChargeIds.contains(loanChargeId)){ + loanCharge.update(amount, dueDate, numberOfRepayments); + loanCharges.add(loanCharge); + } } } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProduct.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProduct.java index f461b17b0..05173e455 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProduct.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProduct.java @@ -61,7 +61,7 @@ import org.apache.fineract.portfolio.fund.domain.Fund; import org.apache.fineract.portfolio.loanaccount.loanschedule.domain.AprCalculator; import org.apache.fineract.portfolio.loanproduct.LoanProductConstants; import org.joda.time.LocalDate; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import com.google.gson.JsonArray; import com.google.gson.JsonObject; @@ -79,7 +79,7 @@ import com.google.gson.JsonObject; @Table(name = "m_product_loan", uniqueConstraints = { @UniqueConstraint(columnNames = { "name" }, name = "unq_name"), @UniqueConstraint(columnNames = { "external_id" }, name = "external_id_UNIQUE"), @UniqueConstraint(columnNames = { "short_name" }, name = "unq_short_name") }) -public class LoanProduct extends AbstractPersistable { +public class LoanProduct extends AbstractPersistableCustom { @ManyToOne @JoinColumn(name = "fund_id", nullable = true) @@ -103,7 +103,7 @@ public class LoanProduct extends AbstractPersistable { private List charges; @Embedded - private final LoanProductRelatedDetail loanProductRelatedDetail; + private LoanProductRelatedDetail loanProductRelatedDetail; @Embedded private LoanProductMinMaxConstraints loanProductMinMaxConstraints; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductBorrowerCycleVariations.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductBorrowerCycleVariations.java index 676377fb9..85f103d9b 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductBorrowerCycleVariations.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductBorrowerCycleVariations.java @@ -26,11 +26,11 @@ import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_product_loan_variations_borrower_cycle") -public class LoanProductBorrowerCycleVariations extends AbstractPersistable { +public class LoanProductBorrowerCycleVariations extends AbstractPersistableCustom { @ManyToOne @JoinColumn(name = "loan_product_id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductConfigurableAttributes.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductConfigurableAttributes.java index 3e2a8f294..2d0893a55 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductConfigurableAttributes.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductConfigurableAttributes.java @@ -25,15 +25,15 @@ import javax.persistence.ManyToOne; import javax.persistence.Table; import org.apache.fineract.infrastructure.core.api.JsonCommand; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.portfolio.loanproduct.LoanProductConstants; -import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @Table(name = "m_product_loan_configurable_attributes") -public class LoanProductConfigurableAttributes extends AbstractPersistable { +public class LoanProductConfigurableAttributes extends AbstractPersistableCustom { @ManyToOne - @JoinColumn(name = "loan_product_id", nullable = true) + @JoinColumn(name = "loan_product_id", nullable = false) private LoanProduct loanProduct; @Column(name = "amortization_method_enum", nullable = true) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductFloatingRates.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductFloatingRates.java index 0c2f476ef..42adbc1e1 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductFloatingRates.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductFloatingRates.java @@ -34,11 +34,11 @@ import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.portfolio.floatingrates.data.FloatingRateDTO; import org.apache.fineract.portfolio.floatingrates.data.FloatingRatePeriodData; import org.apache.fineract.portfolio.floatingrates.domain.FloatingRate; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_product_loan_floating_rates") -public class LoanProductFloatingRates extends AbstractPersistable { +public class LoanProductFloatingRates extends AbstractPersistableCustom { @OneToOne @JoinColumn(name = "loan_product_id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductGuaranteeDetails.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductGuaranteeDetails.java index bc590d39c..a6a96e54e 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductGuaranteeDetails.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductGuaranteeDetails.java @@ -29,7 +29,7 @@ import javax.persistence.Table; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.portfolio.loanproduct.LoanProductConstants; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; /** * Entity for capturing interest recalculation settings @@ -39,7 +39,7 @@ import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @Table(name = "m_product_loan_guarantee_details") -public class LoanProductGuaranteeDetails extends AbstractPersistable { +public class LoanProductGuaranteeDetails extends AbstractPersistableCustom { @OneToOne @JoinColumn(name = "loan_product_id", nullable = false) @@ -48,10 +48,10 @@ public class LoanProductGuaranteeDetails extends AbstractPersistable { @Column(name = "mandatory_guarantee", scale = 6, precision = 19, nullable = false) private BigDecimal mandatoryGuarantee; - @Column(name = "minimum_guarantee_from_own_funds", scale = 6, precision = 19, nullable = false) + @Column(name = "minimum_guarantee_from_own_funds", scale = 6, precision = 19, nullable = true) private BigDecimal minimumGuaranteeFromOwnFunds; - @Column(name = "minimum_guarantee_from_guarantor_funds", scale = 6, precision = 19, nullable = false) + @Column(name = "minimum_guarantee_from_guarantor_funds", scale = 6, precision = 19, nullable = true) private BigDecimal minimumGuaranteeFromGuarantor; protected LoanProductGuaranteeDetails() { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductInterestRecalculationDetails.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductInterestRecalculationDetails.java index 1b5a34faa..e70a14f60 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductInterestRecalculationDetails.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductInterestRecalculationDetails.java @@ -28,7 +28,7 @@ import javax.persistence.Table; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.portfolio.loanproduct.LoanProductConstants; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; /** * Entity for capturing interest recalculation settings @@ -38,7 +38,7 @@ import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @Table(name = "m_product_loan_recalculation_details") -public class LoanProductInterestRecalculationDetails extends AbstractPersistable { +public class LoanProductInterestRecalculationDetails extends AbstractPersistableCustom { @OneToOne @JoinColumn(name = "product_id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductTrancheDetails.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductTrancheDetails.java index c12e742e7..b0eac9f50 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductTrancheDetails.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductTrancheDetails.java @@ -33,10 +33,10 @@ public class LoanProductTrancheDetails { @Column(name = "allow_multiple_disbursals") private boolean multiDisburseLoan; - @Column(name = "max_disbursals", nullable = false) + @Column(name = "max_disbursals", nullable = true) private Integer maxTrancheCount; - @Column(name = "max_outstanding_loan_balance", scale = 6, precision = 19, nullable = false) + @Column(name = "max_outstanding_loan_balance", scale = 6, precision = 19, nullable = true) private BigDecimal outstandingLoanBalance; protected LoanProductTrancheDetails() { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductVariableInstallmentConfig.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductVariableInstallmentConfig.java index 538e452a7..afde1dfea 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductVariableInstallmentConfig.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanProductVariableInstallmentConfig.java @@ -29,11 +29,11 @@ import javax.persistence.Table; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.portfolio.loanproduct.LoanProductConstants; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_product_loan_variable_installment_config") -public class LoanProductVariableInstallmentConfig extends AbstractPersistable { +public class LoanProductVariableInstallmentConfig extends AbstractPersistableCustom { @OneToOne @JoinColumn(name = "loan_product_id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanTransactionProcessingStrategy.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanTransactionProcessingStrategy.java index 775f4b9d6..91df3334d 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanTransactionProcessingStrategy.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/domain/LoanTransactionProcessingStrategy.java @@ -23,11 +23,11 @@ import javax.persistence.Entity; import javax.persistence.Table; import org.apache.fineract.portfolio.loanproduct.data.TransactionProcessingStrategyData; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "ref_loan_transaction_processing_strategy") -public class LoanTransactionProcessingStrategy extends AbstractPersistable { +public class LoanTransactionProcessingStrategy extends AbstractPersistableCustom { @Column(name = "code", unique = true) private String code; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/productmix/domain/ProductMix.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/productmix/domain/ProductMix.java index c0427612f..2bea8cd57 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/productmix/domain/ProductMix.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/productmix/domain/ProductMix.java @@ -24,11 +24,11 @@ import javax.persistence.ManyToOne; import javax.persistence.Table; import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_product_mix") -public class ProductMix extends AbstractPersistable { +public class ProductMix extends AbstractPersistableCustom { @ManyToOne @JoinColumn(name = "product_id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/productmix/domain/ProductMixRepository.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/productmix/domain/ProductMixRepository.java index f4fb6d981..8b9908f55 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/productmix/domain/ProductMixRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/productmix/domain/ProductMixRepository.java @@ -27,9 +27,9 @@ import org.springframework.data.repository.query.Param; public interface ProductMixRepository extends JpaRepository, JpaSpecificationExecutor { - public static final String GET_PRODUCTMIXES_BY_PRODUCTID_SCHEMA = "from ProductMix pm where pm.product.id = :productId"; + public static final String GET_PRODUCTMIXES_BY_PRODUCTID_SCHEMA = "select pm from ProductMix pm where pm.product.id = :productId"; public static final String GET_RESTRICTED_PRODUCTIDS_SCHEMA = "Select pm.restrictedProduct.id from ProductMix pm where pm.product.id = :productId"; - public static final String GET_RESTRICTED_PRODUCTS_SCHEMA = "from ProductMix pm where pm.restrictedProduct.id = :restrictedProductId"; + public static final String GET_RESTRICTED_PRODUCTS_SCHEMA = "select pm from ProductMix pm where pm.restrictedProduct.id = :restrictedProductId"; @Query(GET_PRODUCTMIXES_BY_PRODUCTID_SCHEMA) List findByProductId(@Param("productId") Long productId); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductWritePlatformServiceJpaRepositoryImpl.java index 6e0ab74b3..424b3ac0c 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanProductWritePlatformServiceJpaRepositoryImpl.java @@ -22,6 +22,9 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import javax.persistence.PersistenceException; + +import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.fineract.accounting.producttoaccountmapping.service.ProductToGLAccountMappingWritePlatformService; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; @@ -143,8 +146,12 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro .build(); } catch (final DataIntegrityViolationException dve) { - handleDataIntegrityIssues(command, dve); + handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch(final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -230,8 +237,12 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro .build(); } catch (final DataIntegrityViolationException dve) { - handleDataIntegrityIssues(command, dve); + handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return new CommandProcessingResult(Long.valueOf(-1)); + }catch(final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -281,21 +292,19 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro * Guaranteed to throw an exception no matter what the data integrity issue * is. */ - private void handleDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) { + private void handleDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dve) { - final Throwable realCause = dve.getMostSpecificCause(); - - if (realCause.getMessage().contains("external_id")) { + if (realCause.getMessage().contains("'external_id'")) { final String externalId = command.stringValueOfParameterNamed("externalId"); throw new PlatformDataIntegrityException("error.msg.product.loan.duplicate.externalId", "Loan Product with externalId `" + externalId + "` already exists", "externalId", externalId); - } else if (realCause.getMessage().contains("unq_name")) { + } else if (realCause.getMessage().contains("'unq_name'")) { final String name = command.stringValueOfParameterNamed("name"); throw new PlatformDataIntegrityException("error.msg.product.loan.duplicate.name", "Loan product with name `" + name + "` already exists", "name", name); - } else if (realCause.getMessage().contains("unq_short_name")) { + } else if (realCause.getMessage().contains("'unq_short_name'")) { final String shortName = command.stringValueOfParameterNamed("shortName"); throw new PlatformDataIntegrityException("error.msg.product.loan.duplicate.short.name", "Loan product with short name `" @@ -320,7 +329,7 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro } } - private void logAsErrorUnexpectedDataIntegrityException(final DataIntegrityViolationException dve) { + private void logAsErrorUnexpectedDataIntegrityException(final Exception dve) { logger.error(dve.getMessage(), dve); } } \ No newline at end of file diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/meeting/attendance/domain/ClientAttendance.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/meeting/attendance/domain/ClientAttendance.java index d463190f8..663f954d6 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/meeting/attendance/domain/ClientAttendance.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/meeting/attendance/domain/ClientAttendance.java @@ -27,11 +27,11 @@ import javax.persistence.UniqueConstraint; import org.apache.fineract.portfolio.client.domain.Client; import org.apache.fineract.portfolio.meeting.domain.Meeting; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_client_attendance", uniqueConstraints = { @UniqueConstraint(columnNames = { "client_id", "meeting_id" }, name = "unique_client_meeting_attendance") }) -public class ClientAttendance extends AbstractPersistable { +public class ClientAttendance extends AbstractPersistableCustom { @ManyToOne @JoinColumn(name = "client_id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/meeting/domain/Meeting.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/meeting/domain/Meeting.java index e33459ea8..b61f867f4 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/meeting/domain/Meeting.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/meeting/domain/Meeting.java @@ -51,11 +51,11 @@ import org.apache.fineract.portfolio.calendar.exception.NotValidRecurringDateExc import org.apache.fineract.portfolio.meeting.attendance.domain.ClientAttendance; import org.apache.fineract.portfolio.meeting.exception.MeetingDateException; import org.joda.time.LocalDate; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_meeting", uniqueConstraints = { @UniqueConstraint(columnNames = { "calendar_instance_id", "meeting_date" }, name = "unique_calendar_instance_id_meeting_date") }) -public class Meeting extends AbstractPersistable { +public class Meeting extends AbstractPersistableCustom { @ManyToOne @JoinColumn(name = "calendar_instance_id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/domain/Note.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/domain/Note.java index e835fb056..d5499d44b 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/domain/Note.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/note/domain/Note.java @@ -44,7 +44,7 @@ public class Note extends AbstractAuditableCustom { @ManyToOne @JoinColumn(name = "client_id", nullable = true) - private final Client client; + private Client client; @ManyToOne @JoinColumn(name = "group_id", nullable = true) @@ -62,7 +62,7 @@ public class Note extends AbstractAuditableCustom { private String note; @Column(name = "note_type_enum") - private final Integer noteTypeId; + private Integer noteTypeId; @ManyToOne @JoinColumn(name = "savings_account_id", nullable = true) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/paymentdetail/domain/PaymentDetail.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/paymentdetail/domain/PaymentDetail.java index e66022164..c02bc9de1 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/paymentdetail/domain/PaymentDetail.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/paymentdetail/domain/PaymentDetail.java @@ -32,11 +32,11 @@ import org.apache.fineract.portfolio.paymentdetail.PaymentDetailConstants; import org.apache.fineract.portfolio.paymentdetail.data.PaymentDetailData; import org.apache.fineract.portfolio.paymenttype.data.PaymentTypeData; import org.apache.fineract.portfolio.paymenttype.domain.PaymentType; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_payment_detail") -public final class PaymentDetail extends AbstractPersistable { +public final class PaymentDetail extends AbstractPersistableCustom { @ManyToOne @JoinColumn(name = "payment_type_id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/paymenttype/domain/PaymentType.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/paymenttype/domain/PaymentType.java index 0a5dc08d0..0cdf6bc92 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/paymenttype/domain/PaymentType.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/paymenttype/domain/PaymentType.java @@ -29,11 +29,11 @@ import org.apache.commons.lang.StringUtils; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.portfolio.paymenttype.api.PaymentTypeApiResourceConstants; import org.apache.fineract.portfolio.paymenttype.data.PaymentTypeData; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_payment_type") -public class PaymentType extends AbstractPersistable { +public class PaymentType extends AbstractPersistableCustom { @Column(name = "value") private String name; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountInterestIncentive.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountInterestIncentive.java index 73ba98fa3..e9d331508 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountInterestIncentive.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountInterestIncentive.java @@ -25,11 +25,11 @@ import javax.persistence.ManyToOne; import javax.persistence.Table; import org.apache.fineract.portfolio.interestratechart.domain.InterestIncentivesFields; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_deposit_account_interest_incentives") -public class DepositAccountInterestIncentive extends AbstractPersistable { +public class DepositAccountInterestIncentive extends AbstractPersistableCustom { @ManyToOne @JoinColumn(name = "deposit_account_interest_rate_slab_id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountInterestIncentives.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountInterestIncentives.java index 868968c8a..f9ac7f494 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountInterestIncentives.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountInterestIncentives.java @@ -24,12 +24,12 @@ import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.portfolio.interestratechart.domain.InterestIncentivesFields; -import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @Table(name = "m_savings_interest_incentives") -public class DepositAccountInterestIncentives extends AbstractPersistable { +public class DepositAccountInterestIncentives extends AbstractPersistableCustom { @ManyToOne @JoinColumn(name = "deposit_account_interest_rate_slab_id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountInterestRateChart.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountInterestRateChart.java index 94bd39da3..e124036af 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountInterestRateChart.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountInterestRateChart.java @@ -31,6 +31,7 @@ import javax.persistence.OneToMany; import javax.persistence.OneToOne; import javax.persistence.Table; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.portfolio.client.domain.Client; import org.apache.fineract.portfolio.interestratechart.domain.InterestRateChart; import org.apache.fineract.portfolio.interestratechart.domain.InterestRateChartFields; @@ -39,11 +40,10 @@ import org.apache.fineract.portfolio.interestratechart.incentive.AttributeIncent import org.apache.fineract.portfolio.interestratechart.incentive.AttributeIncentiveCalculationFactory; import org.apache.fineract.portfolio.interestratechart.incentive.IncentiveDTO; import org.joda.time.LocalDate; -import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @Table(name = "m_savings_account_interest_rate_chart") -public class DepositAccountInterestRateChart extends AbstractPersistable { +public class DepositAccountInterestRateChart extends AbstractPersistableCustom { @Embedded private InterestRateChartFields chartFields; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountInterestRateChartSlabs.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountInterestRateChartSlabs.java index 0cca9c9a9..00e197df7 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountInterestRateChartSlabs.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountInterestRateChartSlabs.java @@ -30,14 +30,14 @@ import javax.persistence.ManyToOne; import javax.persistence.OneToMany; import javax.persistence.Table; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.portfolio.interestratechart.domain.InterestIncentives; import org.apache.fineract.portfolio.interestratechart.domain.InterestRateChartSlab; import org.apache.fineract.portfolio.interestratechart.domain.InterestRateChartSlabFields; -import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @Table(name = "m_savings_account_interest_rate_slab") -public class DepositAccountInterestRateChartSlabs extends AbstractPersistable { +public class DepositAccountInterestRateChartSlabs extends AbstractPersistableCustom { @Embedded private InterestRateChartSlabFields slabFields; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountOnHoldTransaction.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountOnHoldTransaction.java index de0c76fbd..067630d87 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountOnHoldTransaction.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountOnHoldTransaction.java @@ -23,7 +23,7 @@ import org.apache.fineract.organisation.monetary.domain.Money; import org.apache.fineract.portfolio.loanaccount.guarantor.domain.GuarantorFundingTransaction; import org.apache.fineract.portfolio.savings.DepositAccountOnHoldTransactionType; import org.joda.time.LocalDate; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import javax.persistence.CascadeType; import javax.persistence.Column; @@ -39,7 +39,7 @@ import java.util.Date; @Entity @Table(name = "m_deposit_account_on_hold_transaction") -public class DepositAccountOnHoldTransaction extends AbstractPersistable { +public class DepositAccountOnHoldTransaction extends AbstractPersistableCustom { @ManyToOne @JoinColumn(name = "savings_account_id", nullable = true) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountRecurringDetail.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountRecurringDetail.java index ff719c525..28e1d1fdb 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountRecurringDetail.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountRecurringDetail.java @@ -36,16 +36,16 @@ import javax.persistence.Table; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.ApiParameterError; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException; import org.apache.fineract.infrastructure.core.service.DateUtils; import org.apache.fineract.organisation.monetary.domain.Money; import org.apache.fineract.portfolio.savings.DepositsApiConstants; import org.joda.time.LocalDate; -import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @Table(name = "m_deposit_account_recurring_detail") -public class DepositAccountRecurringDetail extends AbstractPersistable { +public class DepositAccountRecurringDetail extends AbstractPersistableCustom { @Column(name = "mandatory_recommended_deposit_amount", scale = 6, precision = 19, nullable = true) private BigDecimal mandatoryRecommendedDepositAmount; @@ -54,9 +54,9 @@ public class DepositAccountRecurringDetail extends AbstractPersistable { private BigDecimal totalOverdueAmount; @Column(name = "is_calendar_inherited", nullable = false) - private final boolean isCalendarInherited; + private boolean isCalendarInherited; - @Column(name = "no_of_overdue_installments", nullable = false) + @Column(name = "no_of_overdue_installments", nullable = true) private Integer noOfOverdueInstallments; @Embedded diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountTermAndPreClosure.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountTermAndPreClosure.java index b656afacb..71e7bfaf3 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountTermAndPreClosure.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositAccountTermAndPreClosure.java @@ -42,6 +42,7 @@ import javax.persistence.TemporalType; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.portfolio.savings.DepositAccountOnClosureType; import org.apache.fineract.portfolio.savings.SavingsPeriodFrequencyType; import org.apache.fineract.portfolio.savings.service.SavingsEnumerations; @@ -50,11 +51,10 @@ import org.joda.time.LocalDate; import org.joda.time.Months; import org.joda.time.Weeks; import org.joda.time.Years; -import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @Table(name = "m_deposit_account_term_and_preclosure") -public class DepositAccountTermAndPreClosure extends AbstractPersistable { +public class DepositAccountTermAndPreClosure extends AbstractPersistableCustom { @Column(name = "deposit_amount", scale = 6, precision = 19, nullable = true) private BigDecimal depositAmount; @@ -76,7 +76,7 @@ public class DepositAccountTermAndPreClosure extends AbstractPersistable { @Column(name = "deposit_period_frequency_enum", nullable = true) private Integer depositPeriodFrequency; - @Column(name = "on_account_closure_enum", nullable = false) + @Column(name = "on_account_closure_enum", nullable = true) private Integer onAccountClosureType; @Embedded diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositProductRecurringDetail.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositProductRecurringDetail.java index 1fd290874..1cf315237 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositProductRecurringDetail.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositProductRecurringDetail.java @@ -28,11 +28,11 @@ import javax.persistence.OneToOne; import javax.persistence.Table; import org.apache.fineract.infrastructure.core.api.JsonCommand; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_deposit_product_recurring_detail") -public class DepositProductRecurringDetail extends AbstractPersistable { +public class DepositProductRecurringDetail extends AbstractPersistableCustom { @Embedded private DepositRecurringDetail recurringDetail; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositProductTermAndPreClosure.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositProductTermAndPreClosure.java index 60fb99a5b..0a99f19a4 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositProductTermAndPreClosure.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/DepositProductTermAndPreClosure.java @@ -29,11 +29,11 @@ import javax.persistence.Table; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_deposit_product_term_and_preclosure") -public class DepositProductTermAndPreClosure extends AbstractPersistable { +public class DepositProductTermAndPreClosure extends AbstractPersistableCustom { @Embedded private DepositPreClosureDetail preClosureDetail; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/FixedDepositAccount.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/FixedDepositAccount.java index 1cbc7255b..3807d6e51 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/FixedDepositAccount.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/FixedDepositAccount.java @@ -817,4 +817,10 @@ public class FixedDepositAccount extends SavingsAccount { public BigDecimal minBalanceForInterestCalculation() { return null; } + + @Override + public void loadLazyCollections() { + super.loadLazyCollections(); + this.chart.getId() ; + } } \ No newline at end of file diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/RecurringDepositAccount.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/RecurringDepositAccount.java index f28fe6a5c..6ff9c99e9 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/RecurringDepositAccount.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/RecurringDepositAccount.java @@ -1213,5 +1213,6 @@ public class RecurringDepositAccount extends SavingsAccount { public void loadLazyCollections() { this.depositScheduleInstallments.size() ; super.loadLazyCollections(); + this.chart.getId() ; } } \ No newline at end of file diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/RecurringDepositScheduleInstallment.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/RecurringDepositScheduleInstallment.java index af3d4d768..1f6ea3b93 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/RecurringDepositScheduleInstallment.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/RecurringDepositScheduleInstallment.java @@ -44,15 +44,15 @@ public class RecurringDepositScheduleInstallment extends AbstractAuditableCustom private RecurringDepositAccount account; @Column(name = "installment", nullable = false) - private final Integer installmentNumber; + private Integer installmentNumber; @Temporal(TemporalType.DATE) @Column(name = "fromdate", nullable = true) - private final Date fromDate; + private Date fromDate; @Temporal(TemporalType.DATE) @Column(name = "duedate", nullable = false) - private final Date dueDate; + private Date dueDate; @Column(name = "deposit_amount", scale = 6, precision = 19, nullable = true) private BigDecimal depositAmount; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccount.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccount.java index 3af57f5d7..bc97a6724 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccount.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccount.java @@ -76,6 +76,7 @@ import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder; import org.apache.fineract.infrastructure.core.domain.LocalDateInterval; import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException; import org.apache.fineract.infrastructure.core.service.DateUtils; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.infrastructure.security.service.RandomPasswordGenerator; import org.apache.fineract.organisation.monetary.data.CurrencyData; import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency; @@ -112,7 +113,6 @@ import org.apache.fineract.useradministration.domain.AppUser; import org.joda.time.LocalDate; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; -import org.springframework.data.jpa.domain.AbstractPersistable; import org.springframework.util.CollectionUtils; import com.google.gson.JsonArray; @@ -123,7 +123,7 @@ import com.google.gson.JsonArray; @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name = "deposit_type_enum", discriminatorType = DiscriminatorType.INTEGER) @DiscriminatorValue("100") -public class SavingsAccount extends AbstractPersistable { +public class SavingsAccount extends AbstractPersistableCustom { @Version int version; @@ -293,7 +293,7 @@ public class SavingsAccount extends AbstractPersistable { @OrderBy(value = "dateOf, createdDate, id") @OneToMany(cascade = CascadeType.ALL, mappedBy = "savingsAccount", orphanRemoval = true, fetch=FetchType.LAZY) - protected final List transactions = new ArrayList<>(); + protected List transactions = new ArrayList<>(); @OneToMany(cascade = CascadeType.ALL, mappedBy = "savingsAccount", orphanRemoval = true, fetch=FetchType.LAZY) protected Set charges = new HashSet<>(); @@ -2425,7 +2425,7 @@ public class SavingsAccount extends AbstractPersistable { } // add new charge to savings account - charges().add(savingsAccountCharge); + this.charges.add(savingsAccountCharge); } @@ -2573,7 +2573,7 @@ public class SavingsAccount extends AbstractPersistable { } public Set charges() { - return (this.charges == null) ? new HashSet<>() : this.charges; + return (this.charges == null) ? new HashSet() : this.charges; } public void validateAccountValuesWithProduct() { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountCharge.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountCharge.java index 1c8f85c8f..2ef69a5d8 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountCharge.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountCharge.java @@ -42,6 +42,7 @@ import javax.persistence.TemporalType; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.fineract.infrastructure.core.api.JsonCommand; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency; import org.apache.fineract.organisation.monetary.domain.Money; import org.apache.fineract.organisation.monetary.domain.MoneyHelper; @@ -51,7 +52,6 @@ import org.apache.fineract.portfolio.charge.domain.ChargeTimeType; import org.apache.fineract.portfolio.charge.exception.SavingsAccountChargeWithoutMandatoryFieldException; import org.joda.time.LocalDate; import org.joda.time.MonthDay; -import org.springframework.data.jpa.domain.AbstractPersistable; /** * @author dv6 @@ -59,7 +59,7 @@ import org.springframework.data.jpa.domain.AbstractPersistable; */ @Entity @Table(name = "m_savings_account_charge") -public class SavingsAccountCharge extends AbstractPersistable { +public class SavingsAccountCharge extends AbstractPersistableCustom { @ManyToOne(optional = false) @JoinColumn(name = "savings_account_id", referencedColumnName = "id", nullable = false) @@ -704,15 +704,6 @@ public class SavingsAccountCharge extends AbstractPersistable { .isEquals(); } - @Override - public int hashCode() { - return new HashCodeBuilder(3, 5) // - .append(getId()) // - //.append(this.charge.getId()) // - .append(this.amount).append(getDueLocalDate()) // - .toHashCode(); - } - public BigDecimal updateWithdralFeeAmount(final BigDecimal transactionAmount) { BigDecimal amountPaybale = BigDecimal.ZERO; if (ChargeCalculationType.fromInt(this.chargeCalculation).isFlat()) { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountChargePaidBy.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountChargePaidBy.java index 0d0bb178c..04d6c6be5 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountChargePaidBy.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountChargePaidBy.java @@ -26,11 +26,11 @@ import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_savings_account_charge_paid_by") -public class SavingsAccountChargePaidBy extends AbstractPersistable { +public class SavingsAccountChargePaidBy extends AbstractPersistableCustom { @ManyToOne @JoinColumn(name = "savings_account_transaction_id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountChargeRepository.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountChargeRepository.java index bc0652a23..bd9645cc7 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountChargeRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountChargeRepository.java @@ -31,6 +31,6 @@ public interface SavingsAccountChargeRepository extends JpaRepository findPendingCharges(@Param("transactionDate") Date transactionDate); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountRepository.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountRepository.java index 5a28d6627..df939f672 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountRepository.java @@ -28,25 +28,25 @@ import org.springframework.data.repository.query.Param; //Use SavingsAccountRepositoryWrapper. public interface SavingsAccountRepository extends JpaRepository, JpaSpecificationExecutor { - @Query("from SavingsAccount s_acc where s_acc.client.id = :clientId") + @Query("select s_acc from SavingsAccount s_acc where s_acc.client.id = :clientId") List findSavingAccountByClientId(@Param("clientId") Long clientId); - @Query("from SavingsAccount s_acc where s_acc.status = :status") + @Query("select s_acc from SavingsAccount s_acc where s_acc.status = :status") List findSavingAccountByStatus(@Param("status") Integer status); - @Query("from SavingsAccount sa where sa.client.id = :clientId and sa.group.id = :groupId") + @Query("select sa from SavingsAccount sa where sa.client.id = :clientId and sa.group.id = :groupId") List findByClientIdAndGroupId(@Param("clientId") Long clientId, @Param("groupId") Long groupId); - @Query("select case when (count (saving) > 0) then true else false end from SavingsAccount saving where saving.client.id = :clientId and saving.status in (100,200,300,303,304)") + @Query("select case when (count (saving) > 0) then 'true' else 'false' end from SavingsAccount saving where saving.client.id = :clientId and saving.status in (100,200,300,303,304)") boolean doNonClosedSavingAccountsExistForClient(@Param("clientId") Long clientId); - @Query("from SavingsAccount sa where sa.client.id is null and sa.group.id = :groupId") + @Query("select sa from SavingsAccount sa where sa.client.id is null and sa.group.id = :groupId") List findByGroupId(@Param("groupId") Long groupId); - @Query("from SavingsAccount sa where sa.id = :accountId and sa.depositType = :depositAccountTypeId") + @Query("select sa from SavingsAccount sa where sa.id = :accountId and sa.depositType = :depositAccountTypeId") SavingsAccount findByIdAndDepositAccountType(@Param("accountId") Long accountId, @Param("depositAccountTypeId") Integer depositAccountTypeId); - @Query("from SavingsAccount sa where sa.accountNumber = :accountNumber and sa.status in (100, 200, 300, 303, 304) ") + @Query("select sa from SavingsAccount sa where sa.accountNumber = :accountNumber and sa.status in (100, 200, 300, 303, 304) ") SavingsAccount findNonClosedAccountByAccountNumber(@Param("accountNumber") String accountNumber); } \ No newline at end of file diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountTransaction.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountTransaction.java index c2f2cf434..166f6ed66 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountTransaction.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountTransaction.java @@ -39,6 +39,7 @@ import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.infrastructure.core.domain.LocalDateInterval; import org.apache.fineract.organisation.monetary.data.CurrencyData; import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency; @@ -52,7 +53,6 @@ import org.apache.fineract.portfolio.savings.service.SavingsEnumerations; import org.apache.fineract.portfolio.tax.domain.TaxComponent; import org.apache.fineract.useradministration.domain.AppUser; import org.joda.time.LocalDate; -import org.springframework.data.jpa.domain.AbstractPersistable; import org.springframework.util.CollectionUtils; /** @@ -61,10 +61,10 @@ import org.springframework.util.CollectionUtils; */ @Entity @Table(name = "m_savings_account_transaction") -public final class SavingsAccountTransaction extends AbstractPersistable { +public final class SavingsAccountTransaction extends AbstractPersistableCustom { @ManyToOne(optional = false) - @JoinColumn(name = "savings_account_id", nullable = false) + @JoinColumn(name = "savings_account_id", referencedColumnName="id", nullable = false) private SavingsAccount savingsAccount; @ManyToOne @@ -76,11 +76,11 @@ public final class SavingsAccountTransaction extends AbstractPersistable { private PaymentDetail paymentDetail; @Column(name = "transaction_type_enum", nullable = false) - private final Integer typeOf; + private Integer typeOf; @Temporal(TemporalType.DATE) @Column(name = "transaction_date", nullable = false) - private final Date dateOf; + private Date dateOf; @Column(name = "amount", scale = 6, precision = 19, nullable = false) private BigDecimal amount; @@ -88,28 +88,28 @@ public final class SavingsAccountTransaction extends AbstractPersistable { @Column(name = "is_reversed", nullable = false) private boolean reversed; - @Column(name = "running_balance_derived", scale = 6, precision = 19, nullable = false) + @Column(name = "running_balance_derived", scale = 6, precision = 19, nullable = true) private BigDecimal runningBalance; - @Column(name = "cumulative_balance_derived", scale = 6, precision = 19, nullable = false) + @Column(name = "cumulative_balance_derived", scale = 6, precision = 19, nullable = true) private BigDecimal cumulativeBalance; @Temporal(TemporalType.DATE) - @Column(name = "balance_end_date_derived", nullable = false) + @Column(name = "balance_end_date_derived", nullable = true) private Date balanceEndDate; - @Column(name = "balance_number_of_days_derived", nullable = false) + @Column(name = "balance_number_of_days_derived", nullable = true) private Integer balanceNumberOfDays; @OneToMany(cascade = CascadeType.ALL, mappedBy = "savingsAccountTransaction", orphanRemoval = true, fetch=FetchType.EAGER) - private final Set savingsAccountChargesPaid = new HashSet<>(); + private Set savingsAccountChargesPaid = new HashSet<>(); @Column(name = "overdraft_amount_derived", scale = 6, precision = 19, nullable = true) private BigDecimal overdraftAmount; @Temporal(TemporalType.TIMESTAMP) @Column(name = "created_date", nullable = false) - private final Date createdDate; + private Date createdDate; @ManyToOne @JoinColumn(name = "appuser_id", nullable = true) @@ -117,7 +117,7 @@ public final class SavingsAccountTransaction extends AbstractPersistable { @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch=FetchType.EAGER) @JoinColumn(name = "savings_transaction_id", referencedColumnName = "id", nullable = false) - private final List taxDetails = new ArrayList<>(); + private List taxDetails = new ArrayList<>(); protected SavingsAccountTransaction() { this.dateOf = null; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountTransactionTaxDetails.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountTransactionTaxDetails.java index 4c13b67c6..38d58781c 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountTransactionTaxDetails.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsAccountTransactionTaxDetails.java @@ -26,13 +26,13 @@ import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.organisation.monetary.domain.Money; import org.apache.fineract.portfolio.tax.domain.TaxComponent; -import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @Table(name = "m_savings_account_transaction_tax_details") -public class SavingsAccountTransactionTaxDetails extends AbstractPersistable { +public class SavingsAccountTransactionTaxDetails extends AbstractPersistableCustom { @ManyToOne @JoinColumn(name = "tax_component_id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsProduct.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsProduct.java index aadf2caa2..ba4b4f757 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsProduct.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/domain/SavingsProduct.java @@ -23,6 +23,9 @@ import static org.apache.fineract.portfolio.savings.SavingsApiConstants.accounti import static org.apache.fineract.portfolio.savings.SavingsApiConstants.allowOverdraftParamName; import static org.apache.fineract.portfolio.savings.SavingsApiConstants.chargesParamName; import static org.apache.fineract.portfolio.savings.SavingsApiConstants.currencyCodeParamName; +import static org.apache.fineract.portfolio.savings.SavingsApiConstants.daysToDormancyParamName; +import static org.apache.fineract.portfolio.savings.SavingsApiConstants.daysToEscheatParamName; +import static org.apache.fineract.portfolio.savings.SavingsApiConstants.daysToInactiveParamName; import static org.apache.fineract.portfolio.savings.SavingsApiConstants.descriptionParamName; import static org.apache.fineract.portfolio.savings.SavingsApiConstants.digitsAfterDecimalParamName; import static org.apache.fineract.portfolio.savings.SavingsApiConstants.enforceMinRequiredBalanceParamName; @@ -31,6 +34,7 @@ import static org.apache.fineract.portfolio.savings.SavingsApiConstants.interest import static org.apache.fineract.portfolio.savings.SavingsApiConstants.interestCalculationTypeParamName; import static org.apache.fineract.portfolio.savings.SavingsApiConstants.interestCompoundingPeriodTypeParamName; import static org.apache.fineract.portfolio.savings.SavingsApiConstants.interestPostingPeriodTypeParamName; +import static org.apache.fineract.portfolio.savings.SavingsApiConstants.isDormancyTrackingActiveParamName; import static org.apache.fineract.portfolio.savings.SavingsApiConstants.localeParamName; import static org.apache.fineract.portfolio.savings.SavingsApiConstants.lockinPeriodFrequencyParamName; import static org.apache.fineract.portfolio.savings.SavingsApiConstants.lockinPeriodFrequencyTypeParamName; @@ -43,13 +47,9 @@ import static org.apache.fineract.portfolio.savings.SavingsApiConstants.nominalA import static org.apache.fineract.portfolio.savings.SavingsApiConstants.nominalAnnualInterestRateParamName; import static org.apache.fineract.portfolio.savings.SavingsApiConstants.overdraftLimitParamName; import static org.apache.fineract.portfolio.savings.SavingsApiConstants.shortNameParamName; -import static org.apache.fineract.portfolio.savings.SavingsApiConstants.withdrawalFeeForTransfersParamName; import static org.apache.fineract.portfolio.savings.SavingsApiConstants.taxGroupIdParamName; import static org.apache.fineract.portfolio.savings.SavingsApiConstants.withHoldTaxParamName; -import static org.apache.fineract.portfolio.savings.SavingsApiConstants.isDormancyTrackingActiveParamName; -import static org.apache.fineract.portfolio.savings.SavingsApiConstants.daysToInactiveParamName; -import static org.apache.fineract.portfolio.savings.SavingsApiConstants.daysToDormancyParamName; -import static org.apache.fineract.portfolio.savings.SavingsApiConstants.daysToEscheatParamName; +import static org.apache.fineract.portfolio.savings.SavingsApiConstants.withdrawalFeeForTransfersParamName; import java.math.BigDecimal; import java.util.ArrayList; @@ -78,6 +78,7 @@ import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.ApiParameterError; import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder; import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency; import org.apache.fineract.organisation.monetary.domain.Money; import org.apache.fineract.portfolio.charge.domain.Charge; @@ -89,7 +90,6 @@ import org.apache.fineract.portfolio.savings.SavingsPeriodFrequencyType; import org.apache.fineract.portfolio.savings.SavingsPostingInterestPeriodType; import org.apache.fineract.portfolio.tax.domain.TaxGroup; import org.joda.time.LocalDate; -import org.springframework.data.jpa.domain.AbstractPersistable; import com.google.gson.JsonArray; @@ -99,7 +99,7 @@ import com.google.gson.JsonArray; @Inheritance @DiscriminatorColumn(name = "deposit_type_enum", discriminatorType = DiscriminatorType.INTEGER) @DiscriminatorValue("100") -public class SavingsProduct extends AbstractPersistable { +public class SavingsProduct extends AbstractPersistableCustom { @Column(name = "name", nullable = false, unique = true) protected String name; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java index 5f2834d21..51ffb4f58 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java @@ -256,7 +256,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo depositAccountOnHoldTransactions = this.depositAccountOnHoldTransactionRepository.findBySavingsAccountAndReversedFalseOrderByCreatedDateAsc(account); } account.validateAccountBalanceDoesNotBecomeNegative(SavingsAccountTransactionType.PAY_CHARGE.name(),depositAccountOnHoldTransactions); - this.savingAccountRepositoryWrapper.save(account); + this.savingAccountRepositoryWrapper.saveAndFlush(account); } postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds); @@ -354,7 +354,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo account.validateAccountBalanceDoesNotBecomeNegative(SavingsAccountTransactionType.PAY_CHARGE.name(),depositAccountOnHoldTransactions); - this.savingAccountRepositoryWrapper.save(account); + this.savingAccountRepositoryWrapper.saveAndFlush(account); } postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds); @@ -440,7 +440,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo } private Long saveTransactionToGenerateTransactionId(final SavingsAccountTransaction transaction) { - this.savingsAccountTransactionRepository.save(transaction); + this.savingsAccountTransactionRepository.saveAndFlush(transaction); return transaction.getId(); } @@ -538,7 +538,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo final MathContext mc = new MathContext(10, MoneyHelper.getRoundingMode()); boolean isInterestTransfer = false; account.postInterest(mc, today, isInterestTransfer, isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth); - this.savingAccountRepositoryWrapper.save(account); + this.savingAccountRepositoryWrapper.saveAndFlush(account); postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds); } @@ -629,6 +629,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo account.updateOverduePayments(overdueUptoDate); + this.savingAccountRepositoryWrapper.saveAndFlush(account); postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds); return new CommandProcessingResultBuilder() // @@ -725,6 +726,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo final LocalDate overdueUptoDate = DateUtils.getLocalDateOfTenant(); account.updateOverduePayments(overdueUptoDate); + this.savingAccountRepositoryWrapper.saveAndFlush(account); postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds); return new CommandProcessingResultBuilder() // .withEntityId(newtransactionId) // @@ -926,7 +928,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo financialYearBeginningMonth); this.savingsAccountTransactionRepository.save(newTransferTransaction); - this.savingAccountRepositoryWrapper.save(savingsAccount); + this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount); postJournalEntries(savingsAccount, existingTransactionIds, existingReversedTransactionIds); @@ -959,7 +961,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo financialYearBeginningMonth); this.savingsAccountTransactionRepository.save(withdrawtransferTransaction); - this.savingAccountRepositoryWrapper.save(savingsAccount); + this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount); postJournalEntries(savingsAccount, existingTransactionIds, existingReversedTransactionIds); @@ -1002,7 +1004,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo financialYearBeginningMonth); this.savingsAccountTransactionRepository.save(acceptTransferTransaction); - this.savingAccountRepositoryWrapper.save(savingsAccount); + this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount); postJournalEntries(savingsAccount, existingTransactionIds, existingReversedTransactionIds); @@ -1289,7 +1291,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo account.validateAccountBalanceDoesNotBecomeNegative("." + SavingsAccountTransactionType.PAY_CHARGE.getCode(),depositAccountOnHoldTransactions); - this.savingAccountRepositoryWrapper.save(account); + this.savingAccountRepositoryWrapper.saveAndFlush(account); postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds); } @@ -1313,7 +1315,7 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo ((RecurringDepositAccount) account).updateMaturityStatus(isSavingsInterestPostingAtCurrentPeriodEnd, financialYearBeginningMonth); } - + this.savingAccountRepositoryWrapper.saveAndFlush(account) ; postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl.java index 9dac46094..1da6e8f47 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl.java @@ -30,7 +30,10 @@ import java.util.List; import java.util.Map; import java.util.Set; +import javax.persistence.PersistenceException; + import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.fineract.infrastructure.accountnumberformat.domain.AccountNumberFormat; import org.apache.fineract.infrastructure.accountnumberformat.domain.AccountNumberFormatRepositoryWrapper; import org.apache.fineract.infrastructure.accountnumberformat.domain.EntityAccountType; @@ -88,7 +91,6 @@ import org.apache.fineract.portfolio.savings.domain.SavingsProductRepository; import org.apache.fineract.portfolio.savings.exception.SavingsProductNotFoundException; import org.apache.fineract.useradministration.domain.AppUser; import org.joda.time.LocalDate; -import org.joda.time.LocalTime; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -160,12 +162,11 @@ public class DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl impl * Guaranteed to throw an exception no matter what the data integrity issue * is. */ - private void handleDataIntegrityIssues(final JsonCommand command, final DataAccessException dve) { + private void handleDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dve) { final StringBuilder errorCodeBuilder = new StringBuilder("error.msg.").append(SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME); - final Throwable realCause = dve.getMostSpecificCause(); - if (realCause.getMessage().contains("sa_account_no_UNIQUE")) { + if (realCause.getMessage().contains("'sa_account_no_UNIQUE'")) { final String accountNo = command.stringValueOfParameterNamed("accountNo"); errorCodeBuilder.append(".duplicate.accountNo"); throw new PlatformDataIntegrityException(errorCodeBuilder.toString(), "Savings account with accountNo " + accountNo @@ -235,7 +236,11 @@ public class DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl impl .withSavingsId(savingsId) // .build(); } catch (final DataAccessException dve) { - handleDataIntegrityIssues(command, dve); + handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); + return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(command, throwable, dve); return CommandProcessingResult.empty(); } } @@ -289,7 +294,11 @@ public class DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl impl .withSavingsId(savingsId) // .build(); } catch (final DataAccessException dve) { - handleDataIntegrityIssues(command, dve); + handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); + return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(command, throwable, dve); return CommandProcessingResult.empty(); } } @@ -435,8 +444,12 @@ public class DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl impl .with(changes) // .build(); } catch (final DataAccessException dve) { - handleDataIntegrityIssues(command, dve); + handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return new CommandProcessingResult(Long.valueOf(-1)); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(command, throwable, dve); + return new CommandProcessingResult(Long.valueOf(-1)); } } @@ -502,8 +515,12 @@ public class DepositApplicationProcessWritePlatformServiceJpaRepositoryImpl impl .with(changes) // .build(); } catch (final DataAccessException dve) { - handleDataIntegrityIssues(command, dve); + handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return new CommandProcessingResult(Long.valueOf(-1)); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(command, throwable, dve); + return new CommandProcessingResult(Long.valueOf(-1)); } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/FixedDepositProductWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/FixedDepositProductWritePlatformServiceJpaRepositoryImpl.java index 3da5ef819..73bbcd5bf 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/FixedDepositProductWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/FixedDepositProductWritePlatformServiceJpaRepositoryImpl.java @@ -28,6 +28,9 @@ import java.util.List; import java.util.Map; import java.util.Set; +import javax.persistence.PersistenceException; + +import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.fineract.accounting.producttoaccountmapping.service.ProductToGLAccountMappingWritePlatformService; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.ApiParameterError; @@ -98,8 +101,12 @@ public class FixedDepositProductWritePlatformServiceJpaRepositoryImpl implements .withEntityId(product.getId()) // .build(); } catch (final DataAccessException e) { - handleDataIntegrityIssues(command, e); + handleDataIntegrityIssues(command, e.getMostSpecificCause(), e); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -154,8 +161,12 @@ public class FixedDepositProductWritePlatformServiceJpaRepositoryImpl implements .withEntityId(product.getId()) // .with(changes).build(); } catch (final DataAccessException e) { - handleDataIntegrityIssues(command, e); + handleDataIntegrityIssues(command, e.getMostSpecificCause(), e); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -178,9 +189,8 @@ public class FixedDepositProductWritePlatformServiceJpaRepositoryImpl implements * Guaranteed to throw an exception no matter what the data integrity issue * is. */ - private void handleDataIntegrityIssues(final JsonCommand command, final DataAccessException dae) { + private void handleDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dae) { - final Throwable realCause = dae.getMostSpecificCause(); if (realCause.getMessage().contains("sp_unq_name")) { final String name = command.stringValueOfParameterNamed("name"); @@ -198,7 +208,7 @@ public class FixedDepositProductWritePlatformServiceJpaRepositoryImpl implements "Unknown data integrity issue with resource."); } - private void logAsErrorUnexpectedDataIntegrityException(final DataAccessException dae) { + private void logAsErrorUnexpectedDataIntegrityException(final Exception dae) { this.logger.error(dae.getMessage(), dae); } } \ No newline at end of file diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/RecurringDepositProductWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/RecurringDepositProductWritePlatformServiceJpaRepositoryImpl.java index 330981620..66b448dd2 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/RecurringDepositProductWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/RecurringDepositProductWritePlatformServiceJpaRepositoryImpl.java @@ -19,7 +19,6 @@ package org.apache.fineract.portfolio.savings.service; import static org.apache.fineract.portfolio.savings.DepositsApiConstants.RECURRING_DEPOSIT_PRODUCT_RESOURCE_NAME; -import static org.apache.fineract.portfolio.savings.SavingsApiConstants.SAVINGS_PRODUCT_RESOURCE_NAME; import static org.apache.fineract.portfolio.savings.SavingsApiConstants.accountingRuleParamName; import static org.apache.fineract.portfolio.savings.SavingsApiConstants.chargesParamName; import static org.apache.fineract.portfolio.savings.SavingsApiConstants.taxGroupIdParamName; @@ -29,6 +28,9 @@ import java.util.List; import java.util.Map; import java.util.Set; +import javax.persistence.PersistenceException; + +import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.fineract.accounting.producttoaccountmapping.service.ProductToGLAccountMappingWritePlatformService; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.ApiParameterError; @@ -99,8 +101,12 @@ public class RecurringDepositProductWritePlatformServiceJpaRepositoryImpl implem .withEntityId(product.getId()) // .build(); } catch (final DataAccessException e) { - handleDataIntegrityIssues(command, e); + handleDataIntegrityIssues(command, e.getMostSpecificCause(), e); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -155,8 +161,12 @@ public class RecurringDepositProductWritePlatformServiceJpaRepositoryImpl implem .withEntityId(product.getId()) // .with(changes).build(); } catch (final DataAccessException e) { - handleDataIntegrityIssues(command, e); + handleDataIntegrityIssues(command, e.getMostSpecificCause(), e); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -179,9 +189,8 @@ public class RecurringDepositProductWritePlatformServiceJpaRepositoryImpl implem * Guaranteed to throw an exception no matter what the data integrity issue * is. */ - private void handleDataIntegrityIssues(final JsonCommand command, final DataAccessException dae) { + private void handleDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dae) { - final Throwable realCause = dae.getMostSpecificCause(); if (realCause.getMessage().contains("sp_unq_name")) { final String name = command.stringValueOfParameterNamed("name"); @@ -199,7 +208,7 @@ public class RecurringDepositProductWritePlatformServiceJpaRepositoryImpl implem "Unknown data integrity issue with resource."); } - private void logAsErrorUnexpectedDataIntegrityException(final DataAccessException dae) { + private void logAsErrorUnexpectedDataIntegrityException(final Exception dae) { this.logger.error(dae.getMessage(), dae); } } \ No newline at end of file diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java index 30ce57b30..4c1451ca4 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsAccountWritePlatformServiceJpaRepositoryImpl.java @@ -202,7 +202,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale); processPostActiveActions(account, fmt, existingTransactionIds, existingReversedTransactionIds); - this.savingAccountRepositoryWrapper.save(account); + this.savingAccountRepositoryWrapper.saveAndFlush(account); } postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds); @@ -280,7 +280,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi } private Long saveTransactionToGenerateTransactionId(final SavingsAccountTransaction transaction) { - this.savingsAccountTransactionRepository.save(transaction); + this.savingsAccountTransactionRepository.saveAndFlush(transaction); return transaction.getId(); } @@ -413,7 +413,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi } } - this.savingAccountRepositoryWrapper.save(account); + this.savingAccountRepositoryWrapper.saveAndFlush(account); postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds); } @@ -478,6 +478,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi } account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.undoTransactionAction, depositAccountOnHoldTransactions); account.activateAccountBasedOnBalance(); + this.savingAccountRepositoryWrapper.saveAndFlush(account); postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds); return new CommandProcessingResultBuilder() // @@ -566,6 +567,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi } account.validateAccountBalanceDoesNotBecomeNegative(SavingsApiConstants.adjustTransactionAction, depositAccountOnHoldTransactions); account.activateAccountBasedOnBalance(); + this.savingAccountRepositoryWrapper.saveAndFlush(account); postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds); return new CommandProcessingResultBuilder() // .withEntityId(newtransactionId) // @@ -687,7 +689,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi financialYearBeginningMonth); this.savingsAccountTransactionRepository.save(newTransferTransaction); - this.savingAccountRepositoryWrapper.save(savingsAccount); + this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount); postJournalEntries(savingsAccount, existingTransactionIds, existingReversedTransactionIds); @@ -717,7 +719,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi financialYearBeginningMonth); this.savingsAccountTransactionRepository.save(withdrawtransferTransaction); - this.savingAccountRepositoryWrapper.save(savingsAccount); + this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount); postJournalEntries(savingsAccount, existingTransactionIds, existingReversedTransactionIds); @@ -758,7 +760,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi financialYearBeginningMonth); this.savingsAccountTransactionRepository.save(acceptTransferTransaction); - this.savingAccountRepositoryWrapper.save(savingsAccount); + this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount); postJournalEntries(savingsAccount, existingTransactionIds, existingReversedTransactionIds); @@ -815,7 +817,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); } savingsAccount.addCharge(fmt, savingsAccountCharge, chargeDefinition); - + this.savingsAccountChargeRepository.save(savingsAccountCharge); this.savingAccountRepositoryWrapper.saveAndFlush(savingsAccount); return new CommandProcessingResultBuilder() // @@ -1054,7 +1056,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi account.validateAccountBalanceDoesNotBecomeNegative("." + SavingsAccountTransactionType.PAY_CHARGE.getCode(), depositAccountOnHoldTransactions); - this.savingAccountRepositoryWrapper.save(account); + this.savingAccountRepositoryWrapper.saveAndFlush(account); postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds); } @@ -1245,7 +1247,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi final Set existingReversedTransactionIds = new HashSet<>(); updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds); account.setSubStatusInactive(appuserRepository.fetchSystemUser()); - this.savingAccountRepositoryWrapper.save(account); + this.savingAccountRepositoryWrapper.saveAndFlush(account); postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds); } @@ -1265,7 +1267,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi final Set existingReversedTransactionIds = new HashSet<>(); updateExistingTransactionsDetails(account, existingTransactionIds, existingReversedTransactionIds); account.escheat(appuserRepository.fetchSystemUser()); - this.savingAccountRepositoryWrapper.save(account); + this.savingAccountRepositoryWrapper.saveAndFlush(account); postJournalEntries(account, existingTransactionIds, existingReversedTransactionIds); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl.java index 32e763db1..a63b49cd8 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl.java @@ -27,7 +27,10 @@ import java.util.List; import java.util.Map; import java.util.Set; +import javax.persistence.PersistenceException; + import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.fineract.commands.domain.CommandWrapper; import org.apache.fineract.commands.service.CommandProcessingService; import org.apache.fineract.commands.service.CommandWrapperBuilder; @@ -133,11 +136,10 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl * Guaranteed to throw an exception no matter what the data integrity issue * is. */ - private void handleDataIntegrityIssues(final JsonCommand command, final DataAccessException dve) { + private void handleDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dve) { final StringBuilder errorCodeBuilder = new StringBuilder("error.msg.").append(SavingsApiConstants.SAVINGS_ACCOUNT_RESOURCE_NAME); - final Throwable realCause = dve.getMostSpecificCause(); if (realCause.getMessage().contains("sa_account_no_UNIQUE")) { final String accountNo = command.stringValueOfParameterNamed("accountNo"); errorCodeBuilder.append(".duplicate.accountNo"); @@ -179,8 +181,12 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl .withSavingsId(savingsId) // .build(); } catch (final DataAccessException dve) { - handleDataIntegrityIssues(command, dve); + handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -278,8 +284,12 @@ public class SavingsApplicationProcessWritePlatformServiceJpaRepositoryImpl impl .with(changes) // .build(); } catch (final DataAccessException dve) { - handleDataIntegrityIssues(command, dve); + handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return new CommandProcessingResult(Long.valueOf(-1)); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsProductWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsProductWritePlatformServiceJpaRepositoryImpl.java index a5d4f9c10..7b0711e2a 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsProductWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsProductWritePlatformServiceJpaRepositoryImpl.java @@ -28,6 +28,9 @@ import java.util.List; import java.util.Map; import java.util.Set; +import javax.persistence.PersistenceException; + +import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.fineract.accounting.producttoaccountmapping.service.ProductToGLAccountMappingWritePlatformService; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.ApiParameterError; @@ -37,7 +40,6 @@ import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder; import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException; import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException; import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntityAccessType; -import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntityType; import org.apache.fineract.infrastructure.entityaccess.service.FineractEntityAccessUtil; import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; import org.apache.fineract.portfolio.charge.domain.Charge; @@ -85,9 +87,8 @@ public class SavingsProductWritePlatformServiceJpaRepositoryImpl implements Savi * Guaranteed to throw an exception no matter what the data integrity issue * is. */ - private void handleDataIntegrityIssues(final JsonCommand command, final DataAccessException dae) { + private void handleDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dae) { - final Throwable realCause = dae.getMostSpecificCause(); if (realCause.getMessage().contains("sp_unq_name")) { final String name = command.stringValueOfParameterNamed("name"); @@ -105,7 +106,7 @@ public class SavingsProductWritePlatformServiceJpaRepositoryImpl implements Savi "Unknown data integrity issue with resource."); } - private void logAsErrorUnexpectedDataIntegrityException(final DataAccessException dae) { + private void logAsErrorUnexpectedDataIntegrityException(final Exception dae) { this.logger.error(dae.getMessage(), dae); } @@ -134,8 +135,12 @@ public class SavingsProductWritePlatformServiceJpaRepositoryImpl implements Savi .withEntityId(product.getId()) // .build(); } catch (final DataAccessException e) { - handleDataIntegrityIssues(command, e); + handleDataIntegrityIssues(command, e.getMostSpecificCause(), e); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -189,8 +194,12 @@ public class SavingsProductWritePlatformServiceJpaRepositoryImpl implements Savi .withEntityId(product.getId()) // .with(changes).build(); } catch (final DataAccessException e) { - handleDataIntegrityIssues(command, e); + handleDataIntegrityIssues(command, e.getMostSpecificCause(), e); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(command, throwable, dve); + return CommandProcessingResult.empty(); } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/account/domain/SelfBeneficiariesTPT.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/account/domain/SelfBeneficiariesTPT.java index 76d0432c2..30e0e2041 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/account/domain/SelfBeneficiariesTPT.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/account/domain/SelfBeneficiariesTPT.java @@ -28,12 +28,12 @@ import javax.persistence.Entity; import javax.persistence.Table; import javax.persistence.UniqueConstraint; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_selfservice_beneficiaries_tpt", uniqueConstraints = { @UniqueConstraint(columnNames = { "name", "app_user_id", "is_active" }, name = "name") }) -public class SelfBeneficiariesTPT extends AbstractPersistable { +public class SelfBeneficiariesTPT extends AbstractPersistableCustom { @Column(name = "app_user_id", nullable = false) private Long appUserId; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccount.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccount.java index 7467c4371..085126816 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccount.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccount.java @@ -45,11 +45,11 @@ import org.apache.fineract.portfolio.common.domain.PeriodFrequencyType; import org.apache.fineract.portfolio.savings.domain.SavingsAccount; import org.apache.fineract.portfolio.shareproducts.domain.ShareProduct; import org.apache.fineract.useradministration.domain.AppUser; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_share_account") -public class ShareAccount extends AbstractPersistable { +public class ShareAccount extends AbstractPersistableCustom { @ManyToOne @JoinColumn(name = "client_id", nullable = true) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccountCharge.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccountCharge.java index 7b8a35692..feed81728 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccountCharge.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccountCharge.java @@ -28,18 +28,17 @@ import javax.persistence.ManyToOne; import javax.persistence.Table; import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency; import org.apache.fineract.organisation.monetary.domain.Money; import org.apache.fineract.organisation.monetary.domain.MoneyHelper; import org.apache.fineract.portfolio.charge.domain.Charge; import org.apache.fineract.portfolio.charge.domain.ChargeCalculationType; import org.apache.fineract.portfolio.charge.domain.ChargeTimeType; -import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @Table(name = "m_share_account_charge") -public class ShareAccountCharge extends AbstractPersistable { +public class ShareAccountCharge extends AbstractPersistableCustom { @ManyToOne(optional = false) @JoinColumn(name = "account_id", referencedColumnName = "id", nullable = false) @@ -428,13 +427,4 @@ public class ShareAccountCharge extends AbstractPersistable { .append(this.amount, rhs.amount) // .isEquals(); } - - @Override - public int hashCode() { - return new HashCodeBuilder(3, 5) // - .append(getId()) // - .append(this.charge.getId()) // - .append(this.amount)// - .toHashCode(); - } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccountChargePaidBy.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccountChargePaidBy.java index d9843ebf6..d52d777ca 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccountChargePaidBy.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccountChargePaidBy.java @@ -26,12 +26,12 @@ import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_share_account_charge_paid_by") -public class ShareAccountChargePaidBy extends AbstractPersistable{ +public class ShareAccountChargePaidBy extends AbstractPersistableCustom{ @ManyToOne(optional = false) @JoinColumn(name = "share_transaction_id", referencedColumnName = "id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccountDividendDetails.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccountDividendDetails.java index 40821cb58..5a3d5df17 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccountDividendDetails.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccountDividendDetails.java @@ -24,11 +24,11 @@ import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Table; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_share_account_dividend_details") -public class ShareAccountDividendDetails extends AbstractPersistable { +public class ShareAccountDividendDetails extends AbstractPersistableCustom { @Column(name = "account_id", nullable = false) private Long shareAccountId; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccountTransaction.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccountTransaction.java index 186b18932..9910421ec 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccountTransaction.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/domain/ShareAccountTransaction.java @@ -34,11 +34,11 @@ import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_share_account_transactions") -public class ShareAccountTransaction extends AbstractPersistable { +public class ShareAccountTransaction extends AbstractPersistableCustom { @ManyToOne(optional = false) @JoinColumn(name = "account_id", referencedColumnName = "id", nullable = false) @@ -73,7 +73,7 @@ public class ShareAccountTransaction extends AbstractPersistable { private boolean active = true ; @OneToMany(cascade = CascadeType.ALL, mappedBy = "shareAccountTransaction", orphanRemoval = true, fetch=FetchType.EAGER) - private final Set shareAccountChargesPaid = new HashSet<>(); + private Set shareAccountChargesPaid = new HashSet<>(); protected ShareAccountTransaction() { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/serialization/ShareAccountDataSerializer.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/serialization/ShareAccountDataSerializer.java index 11daee94a..80812affa 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/serialization/ShareAccountDataSerializer.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/serialization/ShareAccountDataSerializer.java @@ -944,6 +944,7 @@ public class ShareAccountDataSerializer { JsonElement element = jsonCommand.parsedJson(); LocalDate closedDate = this.fromApiJsonHelper.extractLocalDateNamed(ShareAccountApiConstants.closeddate_paramname, element); baseDataValidator.reset().parameter(ShareAccountApiConstants.approveddate_paramname).value(closedDate).notNull(); + if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(dataValidationErrors); } boolean isTransactionBeforeExistingTransactions = false ; Set transactions = account.getShareAccountTransactions() ; for(ShareAccountTransaction transaction: transactions) { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountWritePlatformServiceJpaRepositoryImpl.java index 4bf7a85ac..7a2a42235 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareaccounts/service/ShareAccountWritePlatformServiceJpaRepositoryImpl.java @@ -27,7 +27,10 @@ import java.util.List; import java.util.Map; import java.util.Set; +import javax.persistence.PersistenceException; + import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.fineract.accounting.journalentry.service.JournalEntryWritePlatformService; import org.apache.fineract.infrastructure.accountnumberformat.domain.AccountNumberFormat; import org.apache.fineract.infrastructure.accountnumberformat.domain.AccountNumberFormatRepositoryWrapper; @@ -35,6 +38,7 @@ import org.apache.fineract.infrastructure.accountnumberformat.domain.EntityAccou import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder; +import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException; import org.apache.fineract.infrastructure.core.service.DateUtils; import org.apache.fineract.organisation.monetary.data.CurrencyData; import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency; @@ -102,8 +106,12 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA .withEntityId(account.getId()) // .build(); } catch (final DataIntegrityViolationException dve) { - handleDataIntegrityIssues(jsonCommand, dve); + handleDataIntegrityIssues(jsonCommand, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(jsonCommand, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -196,8 +204,12 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA .with(changes) // .build(); } catch (DataIntegrityViolationException dve) { - handleDataIntegrityIssues(jsonCommand, dve); + handleDataIntegrityIssues(jsonCommand, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(jsonCommand, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -226,7 +238,7 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA .with(changes) // .build(); } catch (final DataIntegrityViolationException dve) { - handleDataIntegrityIssues(jsonCommand, dve); + handleDataIntegrityIssues(jsonCommand, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); } } @@ -267,7 +279,7 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA .with(changes) // .build(); } catch (DataIntegrityViolationException dve) { - handleDataIntegrityIssues(jsonCommand, dve); + handleDataIntegrityIssues(jsonCommand, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); } } @@ -301,7 +313,7 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA .with(changes) // .build(); } catch (DataIntegrityViolationException dve) { - handleDataIntegrityIssues(jsonCommand, dve); + handleDataIntegrityIssues(jsonCommand, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); } } @@ -338,7 +350,7 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA .with(changes) // .build(); } catch (DataIntegrityViolationException dve) { - handleDataIntegrityIssues(jsonCommand, dve); + handleDataIntegrityIssues(jsonCommand, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); } } @@ -360,7 +372,7 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA .with(changes) // .build(); } catch (DataIntegrityViolationException dve) { - handleDataIntegrityIssues(jsonCommand, dve); + handleDataIntegrityIssues(jsonCommand, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); } } @@ -397,7 +409,7 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA .with(changes) // .build(); } catch (DataIntegrityViolationException dve) { - handleDataIntegrityIssues(jsonCommand, dve); + handleDataIntegrityIssues(jsonCommand, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); } } @@ -426,7 +438,7 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA .with(changes) // .build(); } catch (DataIntegrityViolationException dve) { - handleDataIntegrityIssues(jsonCommand, dve); + handleDataIntegrityIssues(jsonCommand, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); } } @@ -461,7 +473,7 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA .with(changes) // .build(); } catch (DataIntegrityViolationException dve) { - handleDataIntegrityIssues(jsonCommand, dve); + handleDataIntegrityIssues(jsonCommand, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); } } @@ -495,12 +507,13 @@ public class ShareAccountWritePlatformServiceJpaRepositoryImpl implements ShareA .with(changes) // .build(); } catch (DataIntegrityViolationException dve) { - handleDataIntegrityIssues(jsonCommand, dve); + handleDataIntegrityIssues(jsonCommand, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); } } - private void handleDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) { - + private void handleDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dve) { + throw new PlatformDataIntegrityException("error.msg.shareaccount.unknown.data.integrity.issue", + "Unknown data integrity issue with resource."); } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/domain/ShareProduct.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/domain/ShareProduct.java index 14cc73ad5..a06427f72 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/domain/ShareProduct.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/domain/ShareProduct.java @@ -81,7 +81,7 @@ public class ShareProduct extends AbstractAuditableCustom { @Column(name = "issued_shares", nullable = false) private Long totalSharesIssued; - @Column(name = "totalsubscribed_shares", nullable = false) + @Column(name = "totalsubscribed_shares", nullable = true) private Long totalSubscribedShares; @Column(name = "unit_price", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/domain/ShareProductMarketPrice.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/domain/ShareProductMarketPrice.java index 604214994..2ca7e661b 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/domain/ShareProductMarketPrice.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/domain/ShareProductMarketPrice.java @@ -29,11 +29,11 @@ import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_share_product_market_price") -public class ShareProductMarketPrice extends AbstractPersistable { +public class ShareProductMarketPrice extends AbstractPersistableCustom { @ManyToOne(optional = false) @JoinColumn(name = "product_id", referencedColumnName = "id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/service/ShareProductWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/service/ShareProductWritePlatformServiceJpaRepositoryImpl.java index e9aaac737..2a310a232 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/service/ShareProductWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/shareproducts/service/ShareProductWritePlatformServiceJpaRepositoryImpl.java @@ -21,6 +21,9 @@ package org.apache.fineract.portfolio.shareproducts.service; import java.math.BigDecimal; import java.util.Map; +import javax.persistence.PersistenceException; + +import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.fineract.accounting.producttoaccountmapping.service.ProductToGLAccountMappingWritePlatformService; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; @@ -78,9 +81,13 @@ public class ShareProductWritePlatformServiceJpaRepositoryImpl implements ShareP .withCommandId(jsonCommand.commandId()) // .withEntityId(product.getId()) // .build(); - } catch (final DataIntegrityViolationException dve) { - handleDataIntegrityIssues(jsonCommand, dve); + }catch (DataIntegrityViolationException dve) { + handleDataIntegrityIssues(jsonCommand, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch (PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(jsonCommand, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -105,9 +112,13 @@ public class ShareProductWritePlatformServiceJpaRepositoryImpl implements ShareP .withEntityId(productId) // .with(changes) // .build(); - } catch (DataIntegrityViolationException dve) { - handleDataIntegrityIssues(jsonCommand, dve); + }catch (DataIntegrityViolationException dve) { + handleDataIntegrityIssues(jsonCommand, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch (PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(jsonCommand, throwable, dve); + return CommandProcessingResult.empty(); } } @@ -135,7 +146,7 @@ public class ShareProductWritePlatformServiceJpaRepositoryImpl implements ShareP .withSubEntityId(dividendPayOutDetails.getId())// .build(); } catch (DataIntegrityViolationException dve) { - handleDataIntegrityIssues(jsonCommand, dve); + handleDataIntegrityIssues(dve); return CommandProcessingResult.empty(); } } @@ -175,16 +186,22 @@ public class ShareProductWritePlatformServiceJpaRepositoryImpl implements ShareP } } - private void handleDataIntegrityIssues(final DataIntegrityViolationException dve) { - final Throwable realCause = dve.getMostSpecificCause(); - throw new PlatformDataIntegrityException("error.msg.glClosure.unknown.data.integrity.issue", - "Unknown data integrity issue with resource GL Closure: " + realCause.getMessage()); + private void handleDataIntegrityIssues(final Exception e) { + throw new PlatformDataIntegrityException("error.msg.shareproduct.unknown.data.integrity.issue", + "Unknown data integrity issue with resource."); } - private void handleDataIntegrityIssues(@SuppressWarnings("unused") final JsonCommand command, final DataIntegrityViolationException dve) { - final Throwable realCause = dve.getMostSpecificCause(); - throw new PlatformDataIntegrityException("error.msg.glClosure.unknown.data.integrity.issue", - "Unknown data integrity issue with resource GL Closure: " + realCause.getMessage()); + + private void handleDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dve) { + + if (realCause.getMessage().contains("'name'")) { + final String name = command.stringValueOfParameterNamed(ShareProductApiConstants.name_paramname); + throw new PlatformDataIntegrityException("error.msg.shareproduct.duplicate.name", "Share Product with name `" + name + + "` already exists", "name", name); + } + + throw new PlatformDataIntegrityException("error.msg.shareproduct.unknown.data.integrity.issue", + "Unknown data integrity issue with resource."); } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/spm/domain/Component.java b/fineract-provider/src/main/java/org/apache/fineract/spm/domain/Component.java index 5e7b4a2a3..8a3191b24 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/spm/domain/Component.java +++ b/fineract-provider/src/main/java/org/apache/fineract/spm/domain/Component.java @@ -18,13 +18,13 @@ */ package org.apache.fineract.spm.domain; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import javax.persistence.*; @Entity @Table(name = "m_survey_components") -public class Component extends AbstractPersistable { +public class Component extends AbstractPersistableCustom { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "survey_id") diff --git a/fineract-provider/src/main/java/org/apache/fineract/spm/domain/LookupTable.java b/fineract-provider/src/main/java/org/apache/fineract/spm/domain/LookupTable.java index 1448798e0..26e4ad950 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/spm/domain/LookupTable.java +++ b/fineract-provider/src/main/java/org/apache/fineract/spm/domain/LookupTable.java @@ -18,13 +18,13 @@ */ package org.apache.fineract.spm.domain; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import javax.persistence.*; @Entity @Table(name = "m_survey_lookup_tables") -public class LookupTable extends AbstractPersistable { +public class LookupTable extends AbstractPersistableCustom { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "survey_id") diff --git a/fineract-provider/src/main/java/org/apache/fineract/spm/domain/Question.java b/fineract-provider/src/main/java/org/apache/fineract/spm/domain/Question.java index 861a5c8e5..c33d356d8 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/spm/domain/Question.java +++ b/fineract-provider/src/main/java/org/apache/fineract/spm/domain/Question.java @@ -18,20 +18,20 @@ */ package org.apache.fineract.spm.domain; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import javax.persistence.*; import java.util.List; @Entity @Table(name = "m_survey_questions") -public class Question extends AbstractPersistable { +public class Question extends AbstractPersistableCustom { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "survey_id") private Survey survey; - @OneToMany(mappedBy = "question", fetch = FetchType.LAZY, cascade = CascadeType.ALL) + @OneToMany(mappedBy = "question", fetch = FetchType.EAGER, cascade = CascadeType.ALL) @OrderBy("sequenceNo") private List responses; diff --git a/fineract-provider/src/main/java/org/apache/fineract/spm/domain/Response.java b/fineract-provider/src/main/java/org/apache/fineract/spm/domain/Response.java index 1b742d885..3c9fe33bf 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/spm/domain/Response.java +++ b/fineract-provider/src/main/java/org/apache/fineract/spm/domain/Response.java @@ -18,13 +18,13 @@ */ package org.apache.fineract.spm.domain; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import javax.persistence.*; @Entity @Table(name = "m_survey_responses") -public class Response extends AbstractPersistable { +public class Response extends AbstractPersistableCustom { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "question_id") diff --git a/fineract-provider/src/main/java/org/apache/fineract/spm/domain/Scorecard.java b/fineract-provider/src/main/java/org/apache/fineract/spm/domain/Scorecard.java index 40a926839..0588ca695 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/spm/domain/Scorecard.java +++ b/fineract-provider/src/main/java/org/apache/fineract/spm/domain/Scorecard.java @@ -20,14 +20,14 @@ package org.apache.fineract.spm.domain; import org.apache.fineract.portfolio.client.domain.Client; import org.apache.fineract.useradministration.domain.AppUser; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import javax.persistence.*; import java.util.Date; @Entity @Table(name = "m_survey_scorecards") -public class Scorecard extends AbstractPersistable { +public class Scorecard extends AbstractPersistableCustom { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "survey_id") diff --git a/fineract-provider/src/main/java/org/apache/fineract/spm/domain/Survey.java b/fineract-provider/src/main/java/org/apache/fineract/spm/domain/Survey.java index 8728cdde5..bd6890595 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/spm/domain/Survey.java +++ b/fineract-provider/src/main/java/org/apache/fineract/spm/domain/Survey.java @@ -18,7 +18,7 @@ */ package org.apache.fineract.spm.domain; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import javax.persistence.*; import java.util.Date; @@ -26,13 +26,13 @@ import java.util.List; @Entity @Table(name = "m_surveys") -public class Survey extends AbstractPersistable { +public class Survey extends AbstractPersistableCustom { - @OneToMany(mappedBy = "survey", fetch = FetchType.LAZY, cascade = CascadeType.ALL) + @OneToMany(mappedBy = "survey", fetch = FetchType.EAGER, cascade = CascadeType.ALL) @OrderBy("sequenceNo") private List components; - @OneToMany(mappedBy = "survey", fetch = FetchType.LAZY, cascade = CascadeType.ALL) + @OneToMany(mappedBy = "survey", fetch = FetchType.EAGER, cascade = CascadeType.ALL) @OrderBy("sequenceNo") private List questions; diff --git a/fineract-provider/src/main/java/org/apache/fineract/template/domain/Template.java b/fineract-provider/src/main/java/org/apache/fineract/template/domain/Template.java index c5a066b65..a76654bf1 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/template/domain/Template.java +++ b/fineract-provider/src/main/java/org/apache/fineract/template/domain/Template.java @@ -22,27 +22,19 @@ import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Enumerated; -import javax.persistence.FetchType; -import javax.persistence.OneToMany; -import javax.persistence.OrderBy; -import javax.persistence.Table; -import javax.persistence.UniqueConstraint; +import javax.persistence.*; import org.apache.commons.lang3.StringUtils; import org.apache.fineract.infrastructure.core.api.JsonCommand; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.codehaus.jackson.map.annotate.JsonSerialize; -import org.springframework.data.jpa.domain.AbstractPersistable; import com.google.gson.JsonArray; import com.google.gson.JsonElement; @Entity @Table(name = "m_template", uniqueConstraints = {@UniqueConstraint(columnNames = {"name"}, name = "unq_name")}) -public class Template extends AbstractPersistable { +public class Template extends AbstractPersistableCustom { @Column(name = "name", nullable = false, unique = true) private String name; @@ -60,6 +52,10 @@ public class Template extends AbstractPersistable { @OrderBy(value = "mapperorder") @OneToMany(targetEntity = TemplateMapper.class, cascade = CascadeType.ALL, fetch = FetchType.EAGER) + @JoinTable(name="m_template_m_templatemappers", + joinColumns={@JoinColumn(name="m_template_id", referencedColumnName="id")}, + inverseJoinColumns={@JoinColumn(name="mappers_id", referencedColumnName="id", unique=true)} + ) private List mappers; public Template(final String name, final String text, diff --git a/fineract-provider/src/main/java/org/apache/fineract/template/domain/TemplateMapper.java b/fineract-provider/src/main/java/org/apache/fineract/template/domain/TemplateMapper.java index 30ad3351f..6b034aa93 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/template/domain/TemplateMapper.java +++ b/fineract-provider/src/main/java/org/apache/fineract/template/domain/TemplateMapper.java @@ -22,11 +22,11 @@ import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Table; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_templatemappers") -public class TemplateMapper extends AbstractPersistable { +public class TemplateMapper extends AbstractPersistableCustom { @Column(name = "mapperorder") private int mapperorder; diff --git a/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/AppUser.java b/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/AppUser.java index d52ede0ac..9c8a86f86 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/AppUser.java +++ b/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/AppUser.java @@ -44,6 +44,7 @@ import javax.persistence.UniqueConstraint; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.EnumOptionData; import org.apache.fineract.infrastructure.core.service.DateUtils; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.infrastructure.security.domain.PlatformUser; import org.apache.fineract.infrastructure.security.exception.NoAuthorizationException; import org.apache.fineract.infrastructure.security.service.PlatformPasswordEncoder; @@ -54,14 +55,13 @@ import org.apache.fineract.portfolio.client.domain.Client; import org.apache.fineract.useradministration.service.AppUserConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.data.jpa.domain.AbstractPersistable; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.User; @Entity @Table(name = "m_appuser", uniqueConstraints = @UniqueConstraint(columnNames = { "username" }, name = "username_org")) -public class AppUser extends AbstractPersistable implements PlatformUser { +public class AppUser extends AbstractPersistableCustom implements PlatformUser { private final static Logger logger = LoggerFactory.getLogger(AppUser.class); @@ -84,10 +84,10 @@ public class AppUser extends AbstractPersistable implements PlatformUser { private boolean accountNonExpired; @Column(name = "nonlocked", nullable = false) - private final boolean accountNonLocked; + private boolean accountNonLocked; @Column(name = "nonexpired_credentials", nullable = false) - private final boolean credentialsNonExpired; + private boolean credentialsNonExpired; @Column(name = "enabled", nullable = false) private boolean enabled; diff --git a/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/AppUserClientMapping.java b/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/AppUserClientMapping.java index f4119c430..a0aa2d7f2 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/AppUserClientMapping.java +++ b/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/AppUserClientMapping.java @@ -25,11 +25,11 @@ import javax.persistence.ManyToOne; import javax.persistence.Table; import org.apache.fineract.portfolio.client.domain.Client; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_selfservice_user_client_mapping") -public class AppUserClientMapping extends AbstractPersistable { +public class AppUserClientMapping extends AbstractPersistableCustom { @ManyToOne(optional = false, cascade = CascadeType.PERSIST) @JoinColumn(name = "client_id", nullable = false) diff --git a/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/AppUserPreviousPassword.java b/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/AppUserPreviousPassword.java index ebc61af67..3b18e9ccf 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/AppUserPreviousPassword.java +++ b/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/AppUserPreviousPassword.java @@ -27,11 +27,11 @@ import javax.persistence.Temporal; import javax.persistence.TemporalType; import org.apache.fineract.infrastructure.core.service.DateUtils; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_appuser_previous_password") -public class AppUserPreviousPassword extends AbstractPersistable { +public class AppUserPreviousPassword extends AbstractPersistableCustom { @Column(name = "user_id", nullable = false) private Long userId; diff --git a/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/PasswordValidationPolicy.java b/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/PasswordValidationPolicy.java index f633f763f..545c3804d 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/PasswordValidationPolicy.java +++ b/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/PasswordValidationPolicy.java @@ -25,14 +25,11 @@ import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Table; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_password_validation_policy") -public class PasswordValidationPolicy extends AbstractPersistable { - - // private final static Logger logger = - // LoggerFactory.getLogger(PasswordValidationPolicy.class); +public class PasswordValidationPolicy extends AbstractPersistableCustom { @Column(name = "regex", nullable = false) private String regex; diff --git a/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/PasswordValidationPolicyRepository.java b/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/PasswordValidationPolicyRepository.java index 79de60d05..1fffec7f4 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/PasswordValidationPolicyRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/PasswordValidationPolicyRepository.java @@ -25,7 +25,7 @@ import org.springframework.data.jpa.repository.Query; public interface PasswordValidationPolicyRepository extends JpaRepository, JpaSpecificationExecutor { - @Query("from PasswordValidationPolicy PVP WHERE PVP.active = 1") + @Query("select PVP from PasswordValidationPolicy PVP WHERE PVP.active = true") public PasswordValidationPolicy findActivePasswordValidationPolicy(); diff --git a/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/Permission.java b/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/Permission.java index 10e8d550e..8d636e4b0 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/Permission.java +++ b/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/Permission.java @@ -22,23 +22,23 @@ import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Table; -import org.springframework.data.jpa.domain.AbstractPersistable; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; @Entity @Table(name = "m_permission") -public class Permission extends AbstractPersistable { +public class Permission extends AbstractPersistableCustom { @Column(name = "grouping", nullable = false, length = 45) - private final String grouping; + private String grouping; @Column(name = "code", nullable = false, length = 100) - private final String code; + private String code; @Column(name = "entity_name", nullable = true, length = 100) - private final String entityName; + private String entityName; @Column(name = "action_name", nullable = true, length = 100) - private final String actionName; + private String actionName; @Column(name = "can_maker_checker", nullable = false) private boolean canMakerChecker; diff --git a/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/Role.java b/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/Role.java index fd27b5af2..19b3d98df 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/Role.java +++ b/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/Role.java @@ -34,12 +34,12 @@ import javax.persistence.Table; import javax.persistence.UniqueConstraint; import org.apache.fineract.infrastructure.core.api.JsonCommand; +import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom; import org.apache.fineract.useradministration.data.RoleData; -import org.springframework.data.jpa.domain.AbstractPersistable; @Entity @Table(name = "m_role", uniqueConstraints = { @UniqueConstraint(columnNames = { "name" }, name = "unq_name") }) -public class Role extends AbstractPersistable { +public class Role extends AbstractPersistableCustom { @Column(name = "name", unique = true, nullable = false, length = 100) private String name; @@ -52,7 +52,7 @@ public class Role extends AbstractPersistable { @ManyToMany(fetch = FetchType.EAGER) @JoinTable(name = "m_role_permission", joinColumns = @JoinColumn(name = "role_id"), inverseJoinColumns = @JoinColumn(name = "permission_id")) - private final Set permissions = new HashSet<>(); + private Set permissions = new HashSet<>(); public static Role fromJson(final JsonCommand command) { final String name = command.stringValueOfParameterNamed("name"); diff --git a/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/RoleRepository.java b/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/RoleRepository.java index da9b68ef5..07e830520 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/RoleRepository.java +++ b/fineract-provider/src/main/java/org/apache/fineract/useradministration/domain/RoleRepository.java @@ -25,7 +25,7 @@ import org.springframework.data.repository.query.Param; public interface RoleRepository extends JpaRepository, JpaSpecificationExecutor { - @Query("SELECT COUNT(*) FROM AppUser a JOIN a.roles r WHERE r.id = :roleId AND a.deleted = false") + @Query("SELECT COUNT(a) FROM AppUser a JOIN a.roles r WHERE r.id = :roleId AND a.deleted = false") Integer getCountOfRolesAssociatedWithUsers(@Param("roleId") Long roleId); } \ No newline at end of file diff --git a/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/AppUserWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/AppUserWritePlatformServiceJpaRepositoryImpl.java index a0089fb3d..acda463e8 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/AppUserWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/AppUserWritePlatformServiceJpaRepositoryImpl.java @@ -25,6 +25,10 @@ import java.util.List; import java.util.Map; import java.util.Set; +import javax.persistence.EntityExistsException; +import javax.persistence.PersistenceException; + +import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.fineract.commands.service.CommandWrapperBuilder; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.ApiParameterError; @@ -60,6 +64,7 @@ import org.springframework.cache.annotation.Caching; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; +import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.ObjectUtils; @@ -152,9 +157,15 @@ public class AppUserWritePlatformServiceJpaRepositoryImpl implements AppUserWrit .withOfficeId(userOffice.getId()) // .build(); } catch (final DataIntegrityViolationException dve) { - handleDataIntegrityIssues(command, dve); + handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); - } catch (final PlatformEmailSendException e) { + }catch (final PersistenceException | AuthenticationServiceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(command, throwable, dve); + return new CommandProcessingResultBuilder() // + .withCommandId(command.commandId()) // + .build(); + }catch (final PlatformEmailSendException e) { final List dataValidationErrors = new ArrayList<>(); final String email = command.stringValueOfParameterNamed("email"); @@ -239,9 +250,14 @@ public class AppUserWritePlatformServiceJpaRepositoryImpl implements AppUserWrit .with(changes) // .build(); } catch (final DataIntegrityViolationException dve) { - handleDataIntegrityIssues(command, dve); - + handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); return CommandProcessingResult.empty(); + }catch (final PersistenceException | AuthenticationServiceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(command, throwable, dve); + return new CommandProcessingResultBuilder() // + .withCommandId(command.commandId()) // + .build(); } } @@ -317,10 +333,8 @@ public class AppUserWritePlatformServiceJpaRepositoryImpl implements AppUserWrit * Guaranteed to throw an exception no matter what the data integrity issue * is. */ - private void handleDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) { - - final Throwable realCause = dve.getMostSpecificCause(); - if (realCause.getMessage().contains("username_org")) { + private void handleDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dve) { + if (realCause.getMessage().contains("'username_org'")) { final String username = command.stringValueOfParameterNamed("username"); final StringBuilder defaultMessageBuilder = new StringBuilder("User with username ").append(username) .append(" already exists."); diff --git a/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/RoleWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/RoleWritePlatformServiceJpaRepositoryImpl.java index 21fa9e812..7b4733284 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/RoleWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/useradministration/service/RoleWritePlatformServiceJpaRepositoryImpl.java @@ -22,6 +22,9 @@ import java.util.Collection; import java.util.HashMap; import java.util.Map; +import javax.persistence.PersistenceException; + +import org.apache.commons.lang.exception.ExceptionUtils; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder; @@ -80,7 +83,13 @@ public class RoleWritePlatformServiceJpaRepositoryImpl implements RoleWritePlatf return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(entity.getId()).build(); } catch (final DataIntegrityViolationException dve) { - handleDataIntegrityIssues(command, dve); + handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); + return new CommandProcessingResultBuilder() // + .withCommandId(command.commandId()) // + .build(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(command, throwable, dve); return new CommandProcessingResultBuilder() // .withCommandId(command.commandId()) // .build(); @@ -91,9 +100,8 @@ public class RoleWritePlatformServiceJpaRepositoryImpl implements RoleWritePlatf * Guaranteed to throw an exception no matter what the data integrity issue * is. */ - private void handleDataIntegrityIssues(final JsonCommand command, final DataIntegrityViolationException dve) { + private void handleDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dve) { - final Throwable realCause = dve.getMostSpecificCause(); if (realCause.getMessage().contains("unq_name")) { final String name = command.stringValueOfParameterNamed("name"); @@ -106,7 +114,7 @@ public class RoleWritePlatformServiceJpaRepositoryImpl implements RoleWritePlatf "Unknown data integrity issue with resource."); } - private void logAsErrorUnexpectedDataIntegrityException(final DataIntegrityViolationException dve) { + private void logAsErrorUnexpectedDataIntegrityException(final Exception dve) { logger.error(dve.getMessage(), dve); } @@ -133,7 +141,13 @@ public class RoleWritePlatformServiceJpaRepositoryImpl implements RoleWritePlatf .with(changes) // .build(); } catch (final DataIntegrityViolationException dve) { - handleDataIntegrityIssues(command, dve); + handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); + return new CommandProcessingResultBuilder() // + .withCommandId(command.commandId()) // + .build(); + }catch (final PersistenceException dve) { + Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ; + handleDataIntegrityIssues(command, throwable, dve); return new CommandProcessingResultBuilder() // .withCommandId(command.commandId()) // .build(); diff --git a/fineract-provider/src/main/resources/META-INF/persistence.xml b/fineract-provider/src/main/resources/META-INF/persistence.xml index 65230b7f2..8b1330127 100644 --- a/fineract-provider/src/main/resources/META-INF/persistence.xml +++ b/fineract-provider/src/main/resources/META-INF/persistence.xml @@ -26,11 +26,13 @@ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> - org.hibernate.ejb.HibernatePersistence - - - - - + org.apache.openjpa.persistence.PersistenceProviderImpl + + + + + + + \ No newline at end of file diff --git a/fineract-provider/src/main/resources/META-INF/spring/infrastructure.xml b/fineract-provider/src/main/resources/META-INF/spring/infrastructure.xml index ad8b4182e..e57daaea4 100644 --- a/fineract-provider/src/main/resources/META-INF/spring/infrastructure.xml +++ b/fineract-provider/src/main/resources/META-INF/spring/infrastructure.xml @@ -34,12 +34,7 @@ - - - - - - +