Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FINERACT-849: Switch from OpenJPA to EclipseLink #2127

Merged
merged 1 commit into from Mar 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 8 additions & 4 deletions build.gradle
Expand Up @@ -45,7 +45,8 @@ buildscript {

dependencies {
classpath 'com.bmuschko:gradle-cargo-plugin:2.9.0'
classpath 'org.apache.openjpa:openjpa:3.2.1' // when upgrading, also change OpenJPA version repeated in fineract-provider/build.gradle!
classpath 'org.eclipse.persistence:eclipselink:2.7.10'
classpath 'jakarta.ws.rs:jakarta.ws.rs-api:2.1.6'
classpath('com.google.cloud.tools:jib-layer-filter-extension-gradle:0.1.0')
}
}
Expand Down Expand Up @@ -119,7 +120,7 @@ allprojects {
// We do not use :+ to get the latest available version available on Maven Central, as that could suddenly break things.
// We use the Renovate Bot to automatically propose Pull Requests (PRs) when upgrades for all of these versions are available.

dependency 'org.apache.openjpa:openjpa:3.2.1' // when upgrading, also change OpenJPA version repeated above in buildscript!
dependency 'org.eclipse.persistence:org.eclipse.persistence.jpa:2.7.10'
dependency 'com.google.guava:guava:31.1-jre'
dependency 'com.google.code.gson:gson:2.9.0'
dependency 'com.google.truth:truth:1.1.3'
Expand Down Expand Up @@ -415,7 +416,9 @@ configure(project.fineractJavaProjects) {
"-Xlint:varargs",
"-Xlint:preview",
"-Xlint:static",
"-Werror",
// -Werror needs to be disabled because EclipseLink's static weaving doesn't generate warning-free code
// and during an IntelliJ recompilation, it fails
//"-Werror",
"-Xmaxwarns",
1500,
"-Xmaxerrs",
Expand Down Expand Up @@ -477,7 +480,7 @@ configure(project.fineractJavaProjects) {
licenseMain.dependsOn compileJava
processResources.dependsOn compileJava

// If we are running Gradle within Eclipse to enhance classes with OpenJPA,
// If we are running Gradle within Eclipse to enhance classes,
// set the classes directory to point to Eclipse's default build directory
if (project.hasProperty('env') && project.getProperty('env') == 'eclipse') {
sourceSets.main.java.outputDir = file("$projectDir/bin/main")
Expand Down Expand Up @@ -632,6 +635,7 @@ configure(project.fineractJavaProjects) {
spotbugs {
reportLevel = 'high'
showProgress = false
excludeFilter = file("$rootDir/config/spotbugs/exclude.xml")
}
// https://github.com/spotbugs/spotbugs-gradle-plugin/issues/242
spotbugsMain {
Expand Down
9 changes: 9 additions & 0 deletions config/spotbugs/exclude.xml
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<FindBugsFilter
xmlns="https://github.com/spotbugs/filter/3.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://github.com/spotbugs/filter/3.0.0 https://raw.githubusercontent.com/spotbugs/spotbugs/3.1.0/spotbugs/etc/findbugsfilter.xsd">
<Match>
<Package name="~.*\.domain"/>
</Match>
</FindBugsFilter>
76 changes: 14 additions & 62 deletions fineract-provider/build.gradle
Expand Up @@ -26,70 +26,21 @@ apply plugin: 'com.gorylenko.gradle-git-properties'
apply plugin: 'io.swagger.core.v3.swagger-gradle-plugin'
apply plugin: 'com.google.cloud.tools.jib'

// Custom OpenJPA enhancement
compileJava.doLast {
def enhanceIncludes = [
'**/AbstractPersistableCustom.class',
'**/domain/*.class'
]

def classesToEnhance = project.sourceSets.main.output.classesDirs.collectMany { classesDir ->
project.fileTree(classesDir).matching {
enhanceIncludes.forEach { include it }
}.files
}

String persistenceXml = "META-INF/persistence.xml"
def persistenceXmlFile

// Check if persistence.xml is in the resource dirs.
project.sourceSets.main.resources.srcDirs.collect { resourceDir ->
def persistenceXmlFileCandidate = project.fileTree(resourceDir).matching {
include persistenceXml
}

if (!persistenceXmlFileCandidate.isEmpty()) {
if (persistenceXmlFile == null) {
persistenceXmlFile = persistenceXmlFileCandidate.singleFile
} else {
throw new InvalidUserDataException("Multiple persistence.xml files found in path: " +
persistenceXmlFile + ", " + persistenceXmlFileCandidate)
}
}

// Nothing found. Fallback to plain file.
if (persistenceXmlFile == null) {
persistenceXmlFile = project.file(persistenceXml)
if (!persistenceXmlFile.exists()) {
throw new InvalidUserDataException(
"Could not find valid persistence.xml in path " + this.persistenceXml)
}
}
}

org.apache.openjpa.lib.util.Options options = new org.apache.openjpa.lib.util.Options([
"addDefaultConstructor" : true,
"enforcePropertyRestrictions": true,
"tmpClassLoader" : false,
"propertiesFile" : persistenceXmlFile
])

def classes = project.sourceSets.main.output.classesDirs.collect { it.toURI().toURL() }

def compileJars = project.configurations.compileClasspath.files.collect { jar ->
jar.toURI().toURL()
compileJava.doLast {
def mainSS = sourceSets.main
def source = mainSS.java.classesDirectory.get()
copy {
from "src/main/resources/"
into source
}

def resources = project.sourceSets.main.resources.srcDirs.collect { resource ->
resource.toURI().toURL()
javaexec {
description = 'Performs EclipseLink static weaving of entity classes'
def target = source
main 'org.eclipse.persistence.tools.weaving.jpa.StaticWeave'
args '-persistenceinfo', source, '-classpath', configurations.runtimeClasspath, source, target
classpath configurations.runtimeClasspath
}

def urls = (classes + compileJars + resources)

ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(new URLClassLoader((URL[])urls, currentClassLoader));
org.apache.openjpa.enhance.PCEnhancer.run((String []) classesToEnhance, options);
Thread.currentThread().setContextClassLoader(currentClassLoader);
}

// Configuration for Swagger documentation generation task
Expand Down Expand Up @@ -151,7 +102,8 @@ apply from: 'dependencies.gradle'
modernizer {
ignoreClassNamePatterns = [
'.*AbstractPersistableCustom',
'.*EntityTables'
'.*EntityTables',
'.*domain.*'
]
}

Expand Down
5 changes: 2 additions & 3 deletions fineract-provider/dependencies.gradle
Expand Up @@ -89,9 +89,8 @@ dependencies {
implementation ('org.springframework.boot:spring-boot-starter-data-jpa') {
exclude group: 'org.hibernate'
}
implementation ('org.apache.openjpa:openjpa') {
exclude group: 'org.eclipse.persistence'
exclude group: 'org.apache.geronimo.specs'
implementation('org.eclipse.persistence:org.eclipse.persistence.jpa:2.7.10') {
exclude group: 'org.eclipse.persistence', module: 'jakarta.persistence'
}
implementation ('org.quartz-scheduler:quartz') {
exclude group: 'com.zaxxer', module: 'HikariCP-java7'
Expand Down
Expand Up @@ -74,7 +74,7 @@ public CommandProcessingResult createFinancialActivityAccountMapping(JsonCommand
FinancialActivityAccount financialActivityAccount = FinancialActivityAccount.createNew(glAccount, financialActivityId);

validateFinancialActivityAndAccountMapping(financialActivityAccount);
this.financialActivityAccountRepository.save(financialActivityAccount);
this.financialActivityAccountRepository.saveAndFlush(financialActivityAccount);
return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) //
.withEntityId(financialActivityAccount.getId()) //
Expand Down Expand Up @@ -122,7 +122,7 @@ public CommandProcessingResult updateGLAccountActivityMapping(Long financialActi

if (!changes.isEmpty()) {
validateFinancialActivityAndAccountMapping(financialActivityAccount);
this.financialActivityAccountRepository.save(financialActivityAccount);
this.financialActivityAccountRepository.saveAndFlush(financialActivityAccount);
}
return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) //
Expand Down
Expand Up @@ -107,7 +107,7 @@ public CommandProcessingResult createGLAccount(final JsonCommand command) {

glAccount.generateHierarchy();

this.glAccountRepository.save(glAccount);
this.glAccountRepository.saveAndFlush(glAccount);

return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(glAccount.getId()).build();
} catch (final JpaSystemException | DataIntegrityViolationException dve) {
Expand Down
Expand Up @@ -1098,7 +1098,7 @@ private void createDebitJournalEntryForShares(final Office office, final String
final JournalEntry journalEntry = JournalEntry.createNew(office, paymentDetail, account, currencyCode, modifiedTransactionId,
manualEntry, transactionDate, JournalEntryType.DEBIT, amount, null, PortfolioProductType.SHARES.getValue(), shareAccountId,
null, loanTransaction, savingsAccountTransaction, clientTransaction, shareTransactionId);
this.glJournalEntryRepository.save(journalEntry);
this.glJournalEntryRepository.saveAndFlush(journalEntry);
}

private void createCreditJournalEntryForShares(final Office office, final String currencyCode, final GLAccount account,
Expand All @@ -1117,7 +1117,7 @@ private void createCreditJournalEntryForShares(final Office office, final String
final JournalEntry journalEntry = JournalEntry.createNew(office, paymentDetail, account, currencyCode, modifiedTransactionId,
manualEntry, transactionDate, JournalEntryType.CREDIT, amount, null, PortfolioProductType.SHARES.getValue(), shareAccountId,
null, loanTransaction, savingsAccountTransaction, clientTransaction, shareTransactionId);
this.glJournalEntryRepository.save(journalEntry);
this.glJournalEntryRepository.saveAndFlush(journalEntry);
}

public GLAccount getLinkedGLAccountForLoanProduct(final Long loanProductId, final int accountMappingTypeId, final Long paymentTypeId) {
Expand Down
Expand Up @@ -412,11 +412,11 @@ public String revertProvisioningJournalEntries(final Date reversalTransactionDat
journalEntry.getShareTransactionId());
}
// save the reversal entry
this.glJournalEntryRepository.save(reversalJournalEntry);
this.glJournalEntryRepository.saveAndFlush(reversalJournalEntry);
journalEntry.setReversalJournalEntry(reversalJournalEntry);
journalEntry.setReversed(true);
// save the updated journal entry
this.glJournalEntryRepository.save(journalEntry);
this.glJournalEntryRepository.saveAndFlush(journalEntry);
}
return reversalTransactionId;

Expand Down Expand Up @@ -580,11 +580,11 @@ public void revertShareAccountJournalEntries(final ArrayList<Long> transactionId
journalEntry.getShareTransactionId());
}
// save the reversal entry
this.glJournalEntryRepository.save(reversalJournalEntry);
this.glJournalEntryRepository.saveAndFlush(reversalJournalEntry);
journalEntry.setReversalJournalEntry(reversalJournalEntry);
journalEntry.setReversed(true);
// save the updated journal entry
this.glJournalEntryRepository.save(journalEntry);
this.glJournalEntryRepository.saveAndFlush(journalEntry);
}
}
}
Expand Down
Expand Up @@ -78,7 +78,7 @@ public void saveProductToAccountMapping(final JsonElement element, final String

final ProductToGLAccountMapping accountMapping = new ProductToGLAccountMapping(glAccount, productId,
portfolioProductType.getValue(), placeHolderTypeId);
this.accountMappingRepository.save(accountMapping);
this.accountMappingRepository.saveAndFlush(accountMapping);
}

public void mergeProductToAccountMappingChanges(final JsonElement element, final String paramName, final Long productId,
Expand All @@ -97,7 +97,7 @@ public void mergeProductToAccountMappingChanges(final JsonElement element, final
final GLAccount glAccount = getAccountByIdAndType(paramName, expectedAccountType, accountId);
changes.put(paramName, accountId);
accountMapping.setGlAccount(glAccount);
this.accountMappingRepository.save(accountMapping);
this.accountMappingRepository.saveAndFlush(accountMapping);
}
}
}
Expand All @@ -116,12 +116,12 @@ public void createOrmergeProductToAccountMappingChanges(final JsonElement elemen
changes.put(paramName, accountId);
ProductToGLAccountMapping newAccountMapping = new ProductToGLAccountMapping(glAccount, productId,
portfolioProductType.getValue(), accountTypeId);
this.accountMappingRepository.save(newAccountMapping);
this.accountMappingRepository.saveAndFlush(newAccountMapping);
} else if (!accountMapping.getGlAccount().getId().equals(accountId)) {
final GLAccount glAccount = getAccountByIdAndType(paramName, expectedAccountType, accountId);
changes.put(paramName, accountId);
accountMapping.setGlAccount(glAccount);
this.accountMappingRepository.save(accountMapping);
this.accountMappingRepository.saveAndFlush(accountMapping);
}
}
}
Expand Down Expand Up @@ -258,7 +258,7 @@ public void updateChargeToIncomeAccountMappings(final JsonCommand command, final
allowedAccountTypes, newGLAccountId);
}
chargeToIncomeAccountMapping.setGlAccount(glAccount);
this.accountMappingRepository.save(chargeToIncomeAccountMapping);
this.accountMappingRepository.saveAndFlush(chargeToIncomeAccountMapping);
}
} // deleted payment type
else {
Expand Down Expand Up @@ -334,7 +334,7 @@ public void updatePaymentChannelToFundSourceMappings(final JsonCommand command,
if (!newGLAccountId.equals(existingPaymentChannelToFundSourceMapping.getGlAccount().getId())) {
final GLAccount glAccount = getAccountById(LoanProductAccountingParams.FUND_SOURCE.getValue(), newGLAccountId);
existingPaymentChannelToFundSourceMapping.setGlAccount(glAccount);
this.accountMappingRepository.save(existingPaymentChannelToFundSourceMapping);
this.accountMappingRepository.saveAndFlush(existingPaymentChannelToFundSourceMapping);
}
} // deleted payment type
else {
Expand Down Expand Up @@ -364,7 +364,7 @@ private void savePaymentChannelToFundSourceMapping(final Long productId, final L
final GLAccount glAccount = getAccountById(LoanProductAccountingParams.FUND_SOURCE.getValue(), paymentTypeSpecificFundAccountId);
final ProductToGLAccountMapping accountMapping = new ProductToGLAccountMapping(glAccount, productId,
portfolioProductType.getValue(), CashAccountsForLoan.FUND_SOURCE.getValue(), paymentType);
this.accountMappingRepository.save(accountMapping);
this.accountMappingRepository.saveAndFlush(accountMapping);
}

/**
Expand Down Expand Up @@ -395,7 +395,7 @@ private void saveChargeToFundSourceMapping(final Long productId, final Long char
}
final ProductToGLAccountMapping accountMapping = new ProductToGLAccountMapping(glAccount, productId,
portfolioProductType.getValue(), placeHolderAccountType.getValue(), charge);
this.accountMappingRepository.save(accountMapping);
this.accountMappingRepository.saveAndFlush(accountMapping);
}

private List<GLAccountType> getAllowedAccountTypesForFeeMapping() {
Expand Down
Expand Up @@ -128,7 +128,7 @@ private void revertAndAddJournalEntries(ProvisioningEntryData existingEntryData,
requestedEntry.setJournalEntryCreated(Boolean.TRUE);
}

this.provisioningEntryRepository.save(requestedEntry);
this.provisioningEntryRepository.saveAndFlush(requestedEntry);
this.journalEntryWritePlatformService.createProvisioningJournalEntries(requestedEntry);
}

Expand Down Expand Up @@ -210,7 +210,7 @@ private ProvisioningEntry createProvsioningEntry(Date date, boolean addJournalEn
.retrieveExistingProvisioningIdDateWithJournals();
revertAndAddJournalEntries(exisProvisioningEntryData, requestedEntry);
} else {
this.provisioningEntryRepository.save(requestedEntry);
this.provisioningEntryRepository.saveAndFlush(requestedEntry);
}
return requestedEntry;
}
Expand All @@ -220,10 +220,10 @@ public CommandProcessingResult reCreateProvisioningEntries(Long provisioningEntr
ProvisioningEntry requestedEntry = this.provisioningEntryRepository.findById(provisioningEntryId)
.orElseThrow(() -> new ProvisioningEntryNotfoundException(provisioningEntryId));
requestedEntry.getLoanProductProvisioningEntries().clear();
this.provisioningEntryRepository.save(requestedEntry);
this.provisioningEntryRepository.saveAndFlush(requestedEntry);
Collection<LoanProductProvisioningEntry> entries = generateLoanProvisioningEntry(requestedEntry, requestedEntry.getCreatedDate());
requestedEntry.setProvisioningEntries(entries);
this.provisioningEntryRepository.save(requestedEntry);
this.provisioningEntryRepository.saveAndFlush(requestedEntry);
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(requestedEntry.getId()).build();
}

Expand Down
Expand Up @@ -63,7 +63,7 @@ public CommandProcessingResult createAdHocQuery(final JsonCommand command) {
this.adHocCommandFromApiJsonDeserializer.validateForCreate(command.json());

final AdHoc entity = AdHoc.fromJson(command);
this.adHocRepository.save(entity);
this.adHocRepository.saveAndFlush(entity);

return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(entity.getId()).build();
} catch (final JpaSystemException | DataIntegrityViolationException dve) {
Expand Down
Expand Up @@ -152,7 +152,7 @@ public CommandProcessingResult processAndLogCommand(final CommandWrapper wrapper
public CommandProcessingResult logCommand(CommandSource commandSourceResult) {

commandSourceResult.markAsAwaitingApproval();
commandSourceResult = this.commandSourceRepository.save(commandSourceResult);
commandSourceResult = this.commandSourceRepository.saveAndFlush(commandSourceResult);

return new CommandProcessingResultBuilder().withCommandId(commandSourceResult.getId())
.withEntityId(commandSourceResult.getResourceId()).build();
Expand Down
Expand Up @@ -72,7 +72,7 @@ public CommandProcessingResult createAccountNumberFormat(JsonCommand command) {

AccountNumberFormat accountNumberFormat = new AccountNumberFormat(entityAccountType, accountNumberPrefixType, prefixCharacter);

this.accountNumberFormatRepository.save(accountNumberFormat);
this.accountNumberFormatRepository.saveAndFlush(accountNumberFormat);

return new CommandProcessingResultBuilder() //
.withEntityId(accountNumberFormat.getId()) //
Expand Down
Expand Up @@ -140,7 +140,7 @@ public void onApplicationEvent(final BulkImportEvent event) {
final Workbook workbook = event.getWorkbook();
final Count count = importHandler.process(workbook, event.getLocale(), event.getDateFormat());
importDocument.update(DateUtils.getLocalDateTimeOfTenant(), count.getSuccessCount(), count.getErrorCount());
this.importRepository.save(importDocument);
this.importRepository.saveAndFlush(importDocument);

final Set<String> modifiedParams = new HashSet<>();
modifiedParams.add("fileName");
Expand Down