OpenJPA Integration Changes

This commit is contained in:
Nazeer Hussain Shaik
2016-10-17 11:46:52 +05:30
parent 8d3f7af16f
commit 9d7f1c2197
238 changed files with 1544 additions and 913 deletions
+12 -10
View File
@@ -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 {
+3 -1
View File
@@ -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],
+3 -1
View File
@@ -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],
@@ -155,7 +155,13 @@ 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) ;
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) ;
@@ -163,6 +169,10 @@ public class ProvisioningIntegrationTest {
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);
}
}
@@ -25,6 +25,6 @@ import org.springframework.data.repository.query.Param;
public interface GLClosureRepository extends JpaRepository<GLClosure, Long>, JpaSpecificationExecutor<GLClosure> {
@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);
}
@@ -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<Long> {
public class FinancialActivityAccount extends AbstractPersistableCustom<Long> {
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "gl_account_id")
@@ -26,7 +26,7 @@ import org.springframework.data.repository.query.Param;
public interface FinancialActivityAccountRepository extends JpaRepository<FinancialActivityAccount, Long>,
JpaSpecificationExecutor<FinancialActivityAccount> {
@Query("from FinancialActivityAccount faa where faa.financialActivityType = :financialActivityType")
@Query("select faa from FinancialActivityAccount faa where faa.financialActivityType = :financialActivityType")
FinancialActivityAccount findByFinancialActivityType(@Param("financialActivityType") int financialAccountType);
}
@@ -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,7 +129,11 @@ 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());
@@ -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<Long> {
public class GLAccount extends AbstractPersistableCustom<Long> {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id")
@@ -52,7 +52,7 @@ public class GLAccount extends AbstractPersistable<Long> {
@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id")
private final List<GLAccount> children = new LinkedList<>();
private List<GLAccount> children = new LinkedList<>();
@Column(name = "name", nullable = false, length = 45)
private String name;
@@ -29,24 +29,24 @@ import org.springframework.data.repository.query.Param;
public interface JournalEntryRepository extends JpaRepository<JournalEntry, Long>, JpaSpecificationExecutor<JournalEntry>,
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<JournalEntry> 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<String> 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<String> 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<JournalEntry> 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<JournalEntry> 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);*/
}
@@ -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<Long> {
public class ProductToGLAccountMapping extends AbstractPersistableCustom<Long> {
@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,
@@ -34,22 +34,22 @@ public interface ProductToGLAccountMappingRepository extends JpaRepository<Produ
ProductToGLAccountMapping findByProductIdAndProductTypeAndFinancialAccountTypeAndChargeId(Long productId, int productType,
int financialAccountType, Long chargeId);
@Query("from ProductToGLAccountMapping mapping where mapping.productId =:productId and mapping.productType =:productType and mapping.financialAccountType=:financialAccountType and mapping.paymentType is NULL and mapping.charge is NULL")
@Query("select mapping from ProductToGLAccountMapping mapping where mapping.productId =:productId and mapping.productType =:productType and mapping.financialAccountType=:financialAccountType and mapping.paymentType is NULL and mapping.charge is NULL")
ProductToGLAccountMapping findCoreProductToFinAccountMapping(@Param("productId") Long productId, @Param("productType") int productType,
@Param("financialAccountType") int financialAccountType);
/*** The financial Account Type for a fund source will always be an asset (1) ***/
@Query("from ProductToGLAccountMapping mapping where mapping.productId =:productId and mapping.productType =:productType and mapping.financialAccountType=1 and mapping.paymentType is not NULL")
@Query("select mapping from ProductToGLAccountMapping mapping where mapping.productId =:productId and mapping.productType =:productType and mapping.financialAccountType=1 and mapping.paymentType is not NULL")
List<ProductToGLAccountMapping> 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<ProductToGLAccountMapping> 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<ProductToGLAccountMapping> findAllPenaltyToIncomeAccountMappings(@Param("productId") Long productId,
@Param("productType") int productType);
@@ -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<Long> {
public class LoanProductProvisioningEntry extends AbstractPersistableCustom<Long> {
@ManyToOne(optional = false)
@JoinColumn(name = "history_id", referencedColumnName = "id", nullable = false)
@@ -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<Long> {
public class ProvisioningEntry extends AbstractPersistableCustom<Long> {
@Column(name = "journal_entry_created")
private Boolean isJournalEntryCreated;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "entry", orphanRemoval = true, fetch=FetchType.EAGER)
Set<LoanProductProvisioningEntry> provisioningEntries = new HashSet<>();
private Set<LoanProductProvisioningEntry> provisioningEntries = new HashSet<>();
@OneToOne
@JoinColumn(name = "createdby_id")
@@ -27,9 +27,10 @@ import org.springframework.data.repository.query.Param;
public interface ProvisioningEntryRepository extends JpaRepository<ProvisioningEntry, Long>, JpaSpecificationExecutor<ProvisioningEntry> {
@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() ;
}
@@ -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<Long> {
public class AccountingRule extends AbstractPersistableCustom<Long> {
@Column(name = "name", nullable = false, length = 500)
private String name;
@@ -69,7 +69,7 @@ public class AccountingRule extends AbstractPersistable<Long> {
private Boolean systemDefined;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "accountingRule", orphanRemoval = true, fetch=FetchType.EAGER)
private final List<AccountingTagRule> accountingTagRules = new ArrayList<>();
private List<AccountingTagRule> accountingTagRules = new ArrayList<>();
@Column(name = "allow_multiple_credits", nullable = false)
private boolean allowMultipleCreditEntries;
@@ -25,6 +25,6 @@ import org.springframework.data.repository.query.Param;
public interface AccountingRuleRepository extends JpaRepository<AccountingRule, Long>, JpaSpecificationExecutor<AccountingRule> {
@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);
}
@@ -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<Long> {
public class AccountingTagRule extends AbstractPersistableCustom<Long> {
@ManyToOne
@JoinColumn(name = "acc_rule_id", nullable = false)
@@ -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() + "}");
@@ -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<BatchResponse> errResponseList = new ArrayList<>();
errResponseList.add(errResponse);
return errResponseList;
}
}
}
@@ -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<Long> {
public class CommandSource extends AbstractPersistableCustom<Long> {
@Column(name = "action_name", nullable = true, length = 100)
private String actionName;
@@ -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<Long> {
public class AccountNumberFormat extends AbstractPersistableCustom<Long> {
@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() {
@@ -26,7 +26,7 @@ import org.springframework.data.repository.query.Param;
public interface AccountNumberFormatRepository extends JpaRepository<AccountNumberFormat, Long>,
JpaSpecificationExecutor<AccountNumberFormat> {
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);
@@ -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,7 +77,11 @@ 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,7 +117,11 @@ 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);
@@ -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<Long> {
public class PlatformCache extends AbstractPersistableCustom<Long> {
@Column(name = "cache_type_enum")
private Integer cacheType;
@@ -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<Long> {
public class Code extends AbstractPersistableCustom<Long> {
@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<CodeValue> values;
@@ -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<Long> {
public class CodeValue extends AbstractPersistableCustom<Long> {
@Column(name = "code_value", length = 100)
private String label;
@@ -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,7 +73,11 @@ 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",
@@ -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<Long> {
public class ExternalService extends AbstractPersistableCustom<Long> {
@Column(name = "name", length = 50)
private String name;
@@ -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 {
@@ -49,4 +52,29 @@ public class ExternalServicePropertiesPK implements Serializable {
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();
}
}
@@ -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);
}
}
@@ -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<ExternalServicesProperties, ExternalServicePropertiesPK>,
JpaSpecificationExecutor<ExternalServicesProperties> {
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);
}
@@ -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;
}
@@ -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<Long> {
public class GlobalConfigurationProperty extends AbstractPersistableCustom<Long> {
@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<Long> {
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;
@@ -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<ApiErrorMessageArg> 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,9 +90,14 @@ public class ApiParameterError {
final List<ApiErrorMessageArg> messageArgs = new ArrayList<>();
if (defaultUserMessageArgs != null) {
for (final Object object : defaultUserMessageArgs) {
if(object instanceof Date){
final String formattedDate = dateFormatter.format(object);
messageArgs.add(ApiErrorMessageArg.from(formattedDate));
} else {
messageArgs.add(ApiErrorMessageArg.from(object));
}
}
}
this.args = messageArgs;
this.parameterName = "id";
@@ -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<U, PK extends Serializable> extends AbstractPersistable<PK> implements Auditable<U, PK> {
public abstract class AbstractAuditableCustom<U, PK extends Serializable> extends AbstractPersistableCustom<PK> implements Auditable<AppUser, Long> {
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<U, PK extends Serializable> 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<U, PK extends Serializable> 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<U, PK extends Serializable> 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<U, PK extends Serializable> extend
* .Object)
*/
@Override
public void setLastModifiedBy(final U lastModifiedBy) {
public void setLastModifiedBy(final AppUser lastModifiedBy) {
this.lastModifiedBy = lastModifiedBy;
}
@@ -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<PK extends Serializable> implements Persistable<Long> {
@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
}
@@ -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 ;
}
}
@@ -106,6 +106,7 @@ 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
@@ -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<Long> {
public final class Report extends AbstractPersistableCustom<Long> {
@Column(name = "report_name", nullable = false, unique = true)
private String reportName;
@@ -74,7 +74,7 @@ public final class Report extends AbstractPersistable<Long> {
private String reportSql;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "report", orphanRemoval = true, fetch=FetchType.EAGER)
private final Set<ReportParameterUsage> reportParameterUsages = new HashSet<>();
private Set<ReportParameterUsage> reportParameterUsages = new HashSet<>();
public static Report fromJson(final JsonCommand command, final Collection<String> reportTypes) {
@@ -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<Long> {
public class ReportParameter extends AbstractPersistableCustom<Long> {
protected ReportParameter() {
//
@@ -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<Long> {
public final class ReportParameterUsage extends AbstractPersistableCustom<Long> {
@ManyToOne(optional = false)
@JoinColumn(name = "report_id", nullable = false)
@@ -53,7 +51,7 @@ public final class ReportParameterUsage extends AbstractPersistable<Long> {
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<Long> {
.append(this.parameter.getId()) //
.append(this.reportParameterName) //
.toHashCode();
}
}*/
public boolean hasIdOf(final Long id) {
return getId().equals(id);
@@ -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.");
@@ -573,6 +611,21 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
baseDataValidator.reset().parameter("row").failWithCode("size.too.large");
}
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}catch (final PersistenceException | BadSqlGrammarException ee) {
Throwable realCause = ExceptionUtils.getRootCause(ee.getCause()) ;
final List<ApiParameterError> 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);
}
@@ -941,6 +994,21 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
baseDataValidator.reset().parameter("name").failWithCode("column.already.exists");
}
throwExceptionIfValidationWarningsExist(dataValidationErrors);
}catch (final PersistenceException ee) {
Throwable realCause = ExceptionUtils.getRootCause(ee.getCause()) ;
final List<ApiParameterError> 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);
}
}
@@ -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,7 +103,11 @@ 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,7 +144,11 @@ 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);
@@ -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<Long> {
public class Document extends AbstractPersistableCustom<Long> {
@Column(name = "parent_entity_type", length = 50)
private String parentEntityType;
@@ -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<Long> {
public final class Image extends AbstractPersistableCustom<Long> {
@Column(name = "location", length = 500)
private String location;
@@ -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<Long> {
public class FineractEntityAccess extends AbstractPersistableCustom<Long> {
@Column(name = "entity_type", length = 50)
private String entityType;
@@ -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<Long> {
public class FineractEntityRelation extends AbstractPersistableCustom<Long> {
@OneToMany(cascade = CascadeType.ALL, mappedBy = "relationId", orphanRemoval = true)
private Set<FineractEntityToEntityMapping> fineractEntityToEntityMapping = new HashSet<>();
@@ -24,6 +24,6 @@ import org.springframework.data.repository.query.Param;
public interface FineractEntityRelationRepository extends JpaRepository<FineractEntityRelation, Long>{
@Query("from FineractEntityRelation fea where fea.codeName= :codeName")
@Query("select fea from FineractEntityRelation fea where fea.codeName= :codeName")
FineractEntityRelation findOneByCodeName(@Param("codeName") String codeName);
}
@@ -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<Long> {
public class FineractEntityToEntityMapping extends AbstractPersistableCustom<Long> {
@ManyToOne
@JoinColumn(name = "rel_id")
@@ -50,11 +50,11 @@ public class FineractEntityToEntityMapping extends AbstractPersistable<Long> {
@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;
@@ -27,6 +27,6 @@ public interface FineractEntityToEntityMappingRepository extends JpaRepository<F
@Query("from FineractEntityToEntityMapping feem where feem.fromId= :fromId and feem.toId= :toId and feem.relationId= :relId")
@Query("select feem from FineractEntityToEntityMapping feem where feem.fromId= :fromId and feem.toId= :toId and feem.relationId= :relId")
FineractEntityToEntityMapping findListByProductId(@Param("relId")FineractEntityRelation relId, @Param("toId")Long toId, @Param("fromId")Long fromId );
}
@@ -21,6 +21,9 @@ package org.apache.fineract.infrastructure.entityaccess.service;
import java.util.Date;
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.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
@@ -107,7 +110,11 @@ public class FineractEntityAccessWriteServiceImpl implements FineractEntityAcces
return new CommandProcessingResultBuilder().withEntityId(newMap.getId()).withCommandId(command.commandId()).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();
}
}
@@ -136,7 +143,11 @@ public class FineractEntityAccessWriteServiceImpl implements FineractEntityAcces
return new CommandProcessingResultBuilder(). //
withEntityId(mapForUpdate.getId()).withCommandId(command.commandId()).build();
} catch (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();
}
}
@@ -154,9 +165,8 @@ public class FineractEntityAccessWriteServiceImpl implements FineractEntityAcces
}
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();
realCause.printStackTrace();
if (realCause.getMessage().contains("rel_id_from_id_to_id")) {
final String fromId = command.stringValueOfParameterNamed(FineractEntityApiResourceConstants.fromEnityType);
@@ -169,7 +179,7 @@ public class FineractEntityAccessWriteServiceImpl implements FineractEntityAcces
throw new PlatformDataIntegrityException("error.msg.entity.mapping", "Unknown data integrity issue with resource.");
}
private void logAsErrorUnexpectedDataIntegrityException(final DataIntegrityViolationException dve) {
private void logAsErrorUnexpectedDataIntegrityException(final Exception dve) {
logger.error(dve.getMessage(), dve);
}
@@ -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_configuration")
public class HookConfiguration extends AbstractPersistable<Long> {
public class HookConfiguration extends AbstractPersistableCustom<Long> {
@ManyToOne(optional = false)
@JoinColumn(name = "hook_id", referencedColumnName = "id", nullable = false)
@@ -28,12 +28,12 @@ import org.springframework.data.repository.query.Param;
public interface HookRepository extends JpaRepository<Hook, Long>,
JpaSpecificationExecutor<Hook> {
@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<Hook> 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);
}
@@ -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<Long> {
public class HookResource extends AbstractPersistableCustom<Long> {
@ManyToOne(optional = false)
@JoinColumn(name = "hook_id", referencedColumnName = "id", nullable = false)
@@ -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<Long> {
public class HookTemplate extends AbstractPersistableCustom<Long> {
@Column(name = "name", nullable = false, length = 100)
private String name;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "template", orphanRemoval = true, fetch=FetchType.EAGER)
private final Set<Schema> fields = new HashSet<>();
private Set<Schema> fields = new HashSet<>();
private HookTemplate(final String name) {
@@ -27,6 +27,6 @@ public interface HookTemplateRepository extends
JpaRepository<HookTemplate, Long>,
JpaSpecificationExecutor<HookTemplate> {
@Query("from HookTemplate template where template.name = :name")
@Query("select template from HookTemplate template where template.name = :name")
HookTemplate findOne(@Param("name") String name);
}
@@ -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<Long> {
public class Schema extends AbstractPersistableCustom<Long> {
@ManyToOne(optional = false)
@JoinColumn(name = "hook_template_id", referencedColumnName = "id", nullable = false)
@@ -44,7 +44,7 @@ public class Schema extends AbstractPersistable<Long> {
private String placeholder;
@Column(name = "optional", nullable = false)
private final boolean optional = false;
private boolean optional = false;
public Schema() {
//
@@ -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,7 +139,11 @@ 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(
@@ -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<Long> {
public class ScheduledJobDetail extends AbstractPersistableCustom<Long> {
@Column(name = "name")
private String jobName;
@@ -28,14 +28,14 @@ import org.springframework.data.repository.query.Param;
public interface ScheduledJobDetailRepository extends JpaRepository<ScheduledJobDetail, Long>, JpaSpecificationExecutor<ScheduledJobDetail> {
@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);
}
@@ -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<Long> {
public class ScheduledJobRunHistory extends AbstractPersistableCustom<Long> {
@ManyToOne
@JoinColumn(name = "job_id")
@@ -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<Long> {
public class SchedulerDetail extends AbstractPersistableCustom<Long> {
@Column(name = "execute_misfired_jobs")
private boolean executeInstructionForMisfiredJobs;
@@ -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<Integer> {
public class ReportMailingJobConfiguration extends AbstractPersistableCustom<Integer> {
private static final long serialVersionUID = 3099279770861263184L;
@Column(name = "name", nullable = false)
@@ -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<Long> {
public class ReportMailingJobRunHistory extends AbstractPersistableCustom<Long> {
private static final long serialVersionUID = -3757370929988421076L;
@ManyToOne
@@ -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<Long> {
public class SmsMessage extends AbstractPersistableCustom<Long> {
@ManyToOne
@JoinColumn(name = "group_id", nullable = true)
@@ -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<Long> {
public final class Likelihood extends AbstractPersistableCustom<Long> {
@Column(name = "ppi_name", nullable = false)
private String ppiName;
@@ -29,7 +29,7 @@ import java.util.List;
public interface LikelihoodRepository extends JpaRepository<Likelihood, Long>, JpaSpecificationExecutor<Likelihood> {
@Query("FROM Likelihood WHERE ppi_name =:ppiName AND id !=:id")
@Query("select liklihood FROM Likelihood liklihood WHERE ppi_name =:ppiName AND id <>:id")
List<Likelihood> findByPpiNameAndLikeliHoodId(@Param("ppiName") String ppiName,@Param("id") Long likeliHoodId);
}
@@ -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<Long> {
public class MixTaxonomyMapping extends AbstractPersistableCustom<Long> {
@Column(name = "identifier")
private String identifier;
@@ -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<Long> {
public class Holiday extends AbstractPersistableCustom<Long> {
@Column(name = "name", unique = true, nullable = false, length = 100)
private String name;
@@ -32,6 +32,6 @@ public interface HolidayRepository extends JpaRepository<Holiday, Long>, JpaSpec
List<Holiday> 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<Holiday> findUnprocessed(@Param("status") Integer status);
}
@@ -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,7 +97,11 @@ 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,7 +131,11 @@ 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",
@@ -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<Long> {
public class ApplicationCurrency extends AbstractPersistableCustom<Long> {
@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;
@@ -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;
@@ -29,16 +29,16 @@ import javax.persistence.Embeddable;
public class Money implements Comparable<Money> {
@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"); }
@@ -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<Long> {
public class Office extends AbstractPersistableCustom<Long> {
@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id")
private final List<Office> children = new LinkedList<>();
private List<Office> children = new LinkedList<>();
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "parent_id")
@@ -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<Long> {
public class OfficeTransaction extends AbstractPersistableCustom<Long> {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "from_office_id")
@@ -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<Long> {
public class OrganisationCurrency extends AbstractPersistableCustom<Long> {
@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;
@@ -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,7 +108,11 @@ 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,7 +155,11 @@ 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
@@ -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<Long> {
public class LoanProductProvisionCriteria extends AbstractPersistableCustom<Long> {
@ManyToOne(optional = false)
@JoinColumn(name = "criteria_id", referencedColumnName = "id", nullable = false)
@@ -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<Long> {
public class ProvisioningCategory extends AbstractPersistableCustom<Long> {
@Column(name = "category_name", nullable = false, unique = true)
private String categoryName;
@@ -116,7 +116,7 @@ public class ProvisioningCriteria extends AbstractAuditableCustom<AppUser, Long>
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 ;
}
@@ -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<Long> {
public class ProvisioningCriteriaDefinition extends AbstractPersistableCustom<Long> {
@ManyToOne(optional = false)
@JoinColumn(name = "criteria_id", referencedColumnName = "id", nullable = false)
@@ -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,7 +68,11 @@ 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,7 +103,11 @@ 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 `"
@@ -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,7 +87,11 @@ 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,11 +121,15 @@ public class ProvisioningCriteriaWritePlatformServiceJpaRepositoryImpl implement
final Map<String, Object> 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 `"
@@ -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<Long> {
public class Staff extends AbstractPersistableCustom<Long> {
@Column(name = "firstname", length = 50)
private String firstname;
@@ -57,7 +65,7 @@ public class Staff extends AbstractPersistable<Long> {
@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<Long> {
@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;
@@ -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,7 +77,11 @@ 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,7 +111,11 @@ 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")) {
@@ -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<Long> {
public class Cashier extends AbstractPersistableCustom<Long> {
// ManyToOne(fetch = FetchType.LAZY)
// JoinColumn(name = "office_id", nullable = false)
@@ -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<Long> {
public class CashierTransaction extends AbstractPersistableCustom<Long> {
@Transient
private Office office;
@@ -58,10 +58,10 @@ public class CashierTransaction extends AbstractPersistable<Long> {
@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)
@@ -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<Long> {
public class Teller extends AbstractPersistableCustom<Long> {
@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<Long> {
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<Long> {
@OneToMany(mappedBy = "teller", fetch = FetchType.LAZY)
private Set<Cashier> cashiers;
@OneToMany(mappedBy = "teller", fetch = FetchType.LAZY)
private Set<TellerTransaction> tellerTransactions;
public Teller() {
super();
}
@@ -287,11 +284,8 @@ public class Teller extends AbstractPersistable<Long> {
this.cashiers = cashiers;
}
public Set<TellerTransaction> getTransactions() {
return tellerTransactions;
}
public void setTransactions(Set<TellerTransaction> tellerTransactions) {
this.tellerTransactions = tellerTransactions;
public void initializeLazyCollections() {
this.office.getId();
this.cashiers.size();
}
}
@@ -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);
}
}
@@ -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<Long> {
public class TellerTransaction extends AbstractPersistableCustom<Long> {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "office_id", nullable = false)
@@ -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,7 +118,11 @@ 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<String, Object> changes = teller.update(tellerOffice, command);
if (!changes.isEmpty()) {
this.tellerRepository.saveAndFlush(teller);
this.tellerRepositoryWrapper.saveAndFlush(teller);
}
return new CommandProcessingResultBuilder() //
@@ -150,7 +153,11 @@ 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 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,7 +262,11 @@ 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,7 +302,11 @@ 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,7 +329,11 @@ 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();
}
@@ -444,7 +456,11 @@ 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();
}
}
@@ -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<Long> {
public class WorkingDays extends AbstractPersistableCustom<Long> {
@Column(name = "recurrence", length = 100, nullable = true)
private String recurrence;
@@ -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<Long> {
public class AccountAssociations extends AbstractPersistableCustom<Long> {
@ManyToOne
@JoinColumn(name = "loan_account_id", nullable = true)
@@ -26,9 +26,9 @@ import org.springframework.data.repository.query.Param;
public interface AccountAssociationsRepository extends JpaRepository<AccountAssociations, Long>,
JpaSpecificationExecutor<AccountAssociations> {
@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);
}
@@ -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<Long> {
public class AccountTransferDetails extends AbstractPersistableCustom<Long> {
@ManyToOne
@JoinColumn(name = "from_office_id", nullable = false)
@@ -77,9 +77,9 @@ public class AccountTransferDetails extends AbstractPersistable<Long> {
private Integer transferType;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "accountTransferDetails", orphanRemoval = true, fetch=FetchType.EAGER)
private final List<AccountTransferTransaction> accountTransferTransactions = new ArrayList<>();
private List<AccountTransferTransaction> 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,
@@ -29,15 +29,15 @@ import org.springframework.data.repository.query.Param;
public interface AccountTransferRepository extends JpaRepository<AccountTransferTransaction, Long>,
JpaSpecificationExecutor<AccountTransferTransaction> {
@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<AccountTransferTransaction> 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<AccountTransferTransaction> 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<AccountTransferTransaction> findByFromLoanTransactions(@Param("loanTransactions") Collection<Long> loanTransactions);
}
@@ -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<Long> {
public class AccountTransferStandingInstruction extends AbstractPersistableCustom<Long> {
@ManyToOne
@JoinColumn(name = "account_transfer_details_id", nullable = true)
@@ -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<Long> {
public class AccountTransferTransaction extends AbstractPersistableCustom<Long> {
@ManyToOne
@JoinColumn(name = "account_transfer_details_id", nullable = true)

Some files were not shown because too many files have changed in this diff Show More