You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by ra...@apache.org on 2016/09/21 08:44:26 UTC

[3/4] incubator-fineract git commit: Loading child entites lazy

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/025ff9c7/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java
index 5781082..3e9c1c7 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/client/service/ClientWritePlatformServiceJpaRepositoryImpl.java
@@ -42,8 +42,7 @@ import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityEx
 import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
 import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
 import org.apache.fineract.organisation.office.domain.Office;
-import org.apache.fineract.organisation.office.domain.OfficeRepository;
-import org.apache.fineract.organisation.office.exception.OfficeNotFoundException;
+import org.apache.fineract.organisation.office.domain.OfficeRepositoryWrapper;
 import org.apache.fineract.organisation.staff.domain.Staff;
 import org.apache.fineract.organisation.staff.domain.StaffRepositoryWrapper;
 import org.apache.fineract.portfolio.address.service.AddressWritePlatformService;
@@ -66,15 +65,14 @@ import org.apache.fineract.portfolio.group.domain.GroupRepository;
 import org.apache.fineract.portfolio.group.exception.GroupMemberCountNotInPermissibleRangeException;
 import org.apache.fineract.portfolio.group.exception.GroupNotFoundException;
 import org.apache.fineract.portfolio.loanaccount.domain.Loan;
-import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper;
 import org.apache.fineract.portfolio.note.domain.Note;
 import org.apache.fineract.portfolio.note.domain.NoteRepository;
 import org.apache.fineract.portfolio.savings.data.SavingsAccountDataDTO;
 import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
-import org.apache.fineract.portfolio.savings.domain.SavingsAccountRepository;
+import org.apache.fineract.portfolio.savings.domain.SavingsAccountRepositoryWrapper;
 import org.apache.fineract.portfolio.savings.domain.SavingsProduct;
 import org.apache.fineract.portfolio.savings.domain.SavingsProductRepository;
-import org.apache.fineract.portfolio.savings.exception.SavingsAccountNotFoundException;
 import org.apache.fineract.portfolio.savings.exception.SavingsProductNotFoundException;
 import org.apache.fineract.portfolio.savings.service.SavingsApplicationProcessWritePlatformService;
 import org.apache.fineract.useradministration.domain.AppUser;
@@ -98,15 +96,15 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
     private final PlatformSecurityContext context;
     private final ClientRepositoryWrapper clientRepository;
     private final ClientNonPersonRepositoryWrapper clientNonPersonRepository;
-    private final OfficeRepository officeRepository;
+    private final OfficeRepositoryWrapper officeRepositoryWrapper;
     private final NoteRepository noteRepository;
     private final GroupRepository groupRepository;
     private final ClientDataValidator fromApiJsonDeserializer;
     private final AccountNumberGenerator accountNumberGenerator;
     private final StaffRepositoryWrapper staffRepository;
     private final CodeValueRepositoryWrapper codeValueRepository;
-    private final LoanRepository loanRepository;
-    private final SavingsAccountRepository savingsRepository;
+    private final LoanRepositoryWrapper loanRepositoryWrapper;
+    private final SavingsAccountRepositoryWrapper savingsRepositoryWrapper;
     private final SavingsProductRepository savingsProductRepository;
     private final SavingsApplicationProcessWritePlatformService savingsApplicationProcessWritePlatformService;
     private final CommandProcessingService commandProcessingService;
@@ -118,11 +116,11 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
 
     @Autowired
     public ClientWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
-            final ClientRepositoryWrapper clientRepository, final ClientNonPersonRepositoryWrapper clientNonPersonRepository, final OfficeRepository officeRepository, final NoteRepository noteRepository,
+            final ClientRepositoryWrapper clientRepository, final ClientNonPersonRepositoryWrapper clientNonPersonRepository, final OfficeRepositoryWrapper officeRepositoryWrapper, final NoteRepository noteRepository,
             final ClientDataValidator fromApiJsonDeserializer, final AccountNumberGenerator accountNumberGenerator,
             final GroupRepository groupRepository, final StaffRepositoryWrapper staffRepository,
-            final CodeValueRepositoryWrapper codeValueRepository, final LoanRepository loanRepository,
-            final SavingsAccountRepository savingsRepository, final SavingsProductRepository savingsProductRepository,
+            final CodeValueRepositoryWrapper codeValueRepository, final LoanRepositoryWrapper loanRepositoryWrapper,
+            final SavingsAccountRepositoryWrapper savingsRepositoryWrapper, final SavingsProductRepository savingsProductRepository,
             final SavingsApplicationProcessWritePlatformService savingsApplicationProcessWritePlatformService,
             final CommandProcessingService commandProcessingService, final ConfigurationDomainService configurationDomainService,
             final AccountNumberFormatRepositoryWrapper accountNumberFormatRepository, final FromJsonHelper fromApiJsonHelper,
@@ -131,15 +129,15 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
         this.context = context;
         this.clientRepository = clientRepository;
         this.clientNonPersonRepository = clientNonPersonRepository;
-        this.officeRepository = officeRepository;
+        this.officeRepositoryWrapper = officeRepositoryWrapper;
         this.noteRepository = noteRepository;
         this.fromApiJsonDeserializer = fromApiJsonDeserializer;
         this.accountNumberGenerator = accountNumberGenerator;
         this.groupRepository = groupRepository;
         this.staffRepository = staffRepository;
         this.codeValueRepository = codeValueRepository;
-        this.loanRepository = loanRepository;
-        this.savingsRepository = savingsRepository;
+        this.loanRepositoryWrapper = loanRepositoryWrapper;
+        this.savingsRepositoryWrapper = savingsRepositoryWrapper;
         this.savingsProductRepository = savingsProductRepository;
         this.savingsApplicationProcessWritePlatformService = savingsApplicationProcessWritePlatformService;
         this.commandProcessingService = commandProcessingService;
@@ -217,8 +215,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
 
             final Long officeId = command.longValueOfParameterNamed(ClientApiConstants.officeIdParamName);
 
-            final Office clientOffice = this.officeRepository.findOne(officeId);
-            if (clientOffice == null) { throw new OfficeNotFoundException(officeId); }
+            final Office clientOffice = this.officeRepositoryWrapper.findOneWithNotFoundDetection(officeId);
 
             final Long groupId = command.longValueOfParameterNamed(ClientApiConstants.groupIdParamName);
 
@@ -254,12 +251,11 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
                         ClientApiConstants.CLIENT_CLASSIFICATION, clientClassificationId);
             }
 
-            SavingsProduct savingsProduct = null;
+           
             final Long savingsProductId = command.longValueOfParameterNamed(ClientApiConstants.savingsProductIdParamName);
             if (savingsProductId != null) {
-                savingsProduct = this.savingsProductRepository.findOne(savingsProductId);
+                SavingsProduct savingsProduct = this.savingsProductRepository.findOne(savingsProductId);
                 if (savingsProduct == null) { throw new SavingsProductNotFoundException(savingsProductId); }
-
             }
             
             final Integer legalFormParamValue = command.integerValueOfParameterNamed(ClientApiConstants.legalFormIdParamName);
@@ -275,7 +271,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
                 }
             }
             
-            final Client newClient = Client.createNew(currentUser, clientOffice, clientParentGroup, staff, savingsProduct, gender,
+            final Client newClient = Client.createNew(currentUser, clientOffice, clientParentGroup, staff, savingsProductId, gender,
                     clientType, clientClassification, legalFormValue, command);
             boolean rollbackTransaction = false;
             if (newClient.isActive()) {
@@ -300,16 +296,13 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
                 
             }
             
-            if(isEntity)            
-            	extractAndCreateClientNonPerson(newClient, command);
+            if(isEntity) {
+                extractAndCreateClientNonPerson(newClient, command);
+            }
             	
-			final long clientId = newClient.getId();
-
-			if (isAddressEnabled) {
-
-				this.addressWritePlatformService.addNewClientAddress(newClient, command);
-
-			}
+            if (isAddressEnabled) {
+                this.addressWritePlatformService.addNewClientAddress(newClient, command);
+            }
 
 
             return new CommandProcessingResultBuilder() //
@@ -408,7 +401,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
                     savingsProduct = this.savingsProductRepository.findOne(savingsProductId);
                     if (savingsProduct == null) { throw new SavingsProductNotFoundException(savingsProductId); }
                 }
-                clientForUpdate.updateSavingsProduct(savingsProduct);
+                clientForUpdate.updateSavingsProduct(savingsProductId);
             }
 
             if (changes.containsKey(ClientApiConstants.genderIdParamName)) {
@@ -518,7 +511,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
         try {
             this.fromApiJsonDeserializer.validateActivation(command);
 
-            final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId);
+            final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId, true);
             validateParentGroupRulesBeforeClientActivation(client);
 
             final Locale locale = command.extractLocale();
@@ -546,13 +539,13 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
 
     private CommandProcessingResult openSavingsAccount(final Client client, final DateTimeFormatter fmt) {
         CommandProcessingResult commandProcessingResult = CommandProcessingResult.empty();
-        if (client.isActive() && client.SavingsProduct() != null) {
-            SavingsAccountDataDTO savingsAccountDataDTO = new SavingsAccountDataDTO(client, null, client.SavingsProduct(),
+        if (client.isActive() && client.savingsProductId() != null) {
+            SavingsAccountDataDTO savingsAccountDataDTO = new SavingsAccountDataDTO(client, null, client.savingsProductId(),
                     client.getActivationLocalDate(), client.activatedBy(), fmt);
             commandProcessingResult = this.savingsApplicationProcessWritePlatformService.createActiveApplication(savingsAccountDataDTO);
             if (commandProcessingResult.getSavingsId() != null) {
-                SavingsAccount savingsAccount = this.savingsRepository.findOne(commandProcessingResult.getSavingsId());
-                client.updateSavingsAccount(savingsAccount);
+                this.savingsRepositoryWrapper.findOneWithNotFoundDetection(commandProcessingResult.getSavingsId());
+                client.updateSavingsAccount(commandProcessingResult.getSavingsId());
                 client.updateSavingsProduct(null);
             }
         }
@@ -660,9 +653,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
                 throw new InvalidClientStateTransitionException("close", "date.cannot.before.client.actvation.date", errorMessage,
                         closureDate, client.getActivationLocalDate());
             }
-
-            final List<Loan> clientLoans = this.loanRepository.findLoanByClientId(clientId);
-
+            final List<Loan> clientLoans = this.loanRepositoryWrapper.findLoanByClientId(clientId);
             for (final Loan loan : clientLoans) {
                 final LoanStatusMapper loanStatus = new LoanStatusMapper(loan.status().getValue());
                 if (loanStatus.isOpen() || loanStatus.isPendingApproval() || loanStatus.isAwaitingDisbursal()) {
@@ -677,7 +668,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
                     throw new InvalidClientStateTransitionException("close", "loan.overpaid", errorMessage);
                 }
             }
-            final List<SavingsAccount> clientSavingAccounts = this.savingsRepository.findSavingAccountByClientId(clientId);
+            final List<SavingsAccount> clientSavingAccounts = this.savingsRepositoryWrapper.findSavingAccountByClientId(clientId);
 
             for (final SavingsAccount saving : clientSavingAccounts) {
                 if (saving.isActive() || saving.isSubmittedAndPendingApproval() || saving.isApproved()) {
@@ -714,14 +705,13 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
         SavingsAccount savingsAccount = null;
         final Long savingsId = command.longValueOfParameterNamed(ClientApiConstants.savingsAccountIdParamName);
         if (savingsId != null) {
-            savingsAccount = this.savingsRepository.findOne(savingsId);
-            if (savingsAccount == null) { throw new SavingsAccountNotFoundException(savingsId); }
+            savingsAccount = this.savingsRepositoryWrapper.findOneWithNotFoundDetection(savingsId);
             if (!savingsAccount.getClient().identifiedBy(clientId)) {
                 String defaultUserMessage = "saving account must belongs to client";
                 throw new InvalidClientSavingProductException("saving.account", "must.belongs.to.client", defaultUserMessage, savingsId,
                         clientForUpdate.getId());
             }
-            clientForUpdate.updateSavingsAccount(savingsAccount);
+            clientForUpdate.updateSavingsAccount(savingsId);
         }
 
         this.clientRepository.saveAndFlush(clientForUpdate);

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/025ff9c7/fineract-provider/src/main/java/org/apache/fineract/portfolio/collateral/service/CollateralReadPlatformServiceImpl.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/collateral/service/CollateralReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/collateral/service/CollateralReadPlatformServiceImpl.java
index bf9d10e..69a7010 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/collateral/service/CollateralReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/collateral/service/CollateralReadPlatformServiceImpl.java
@@ -30,9 +30,7 @@ import org.apache.fineract.infrastructure.security.service.PlatformSecurityConte
 import org.apache.fineract.organisation.monetary.data.CurrencyData;
 import org.apache.fineract.portfolio.collateral.data.CollateralData;
 import org.apache.fineract.portfolio.collateral.exception.CollateralNotFoundException;
-import org.apache.fineract.portfolio.loanaccount.domain.Loan;
-import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository;
-import org.apache.fineract.portfolio.loanaccount.exception.LoanNotFoundException;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.dao.EmptyResultDataAccessException;
 import org.springframework.jdbc.core.JdbcTemplate;
@@ -44,14 +42,14 @@ public class CollateralReadPlatformServiceImpl implements CollateralReadPlatform
 
     private final JdbcTemplate jdbcTemplate;
     private final PlatformSecurityContext context;
-    private final LoanRepository loanRepository;
+    private final LoanRepositoryWrapper loanRepositoryWrapper;
 
     @Autowired
     public CollateralReadPlatformServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
-            final LoanRepository loanRepository) {
+            final LoanRepositoryWrapper loanRepositoryWrapper) {
         this.context = context;
         this.jdbcTemplate = new JdbcTemplate(dataSource);
-        this.loanRepository = loanRepository;
+        this.loanRepositoryWrapper = loanRepositoryWrapper;
     }
 
     private static final class CollateralMapper implements RowMapper<CollateralData> {
@@ -119,8 +117,7 @@ public class CollateralReadPlatformServiceImpl implements CollateralReadPlatform
 
     @Override
     public List<CollateralData> retrieveCollateralsForValidLoan(final Long loanId) {
-        final Loan loan = this.loanRepository.findOne(loanId);
-        if (loan == null) { throw new LoanNotFoundException(loanId); }
+        this.loanRepositoryWrapper.findOneWithNotFoundDetection(loanId);
         return retrieveCollaterals(loanId);
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/025ff9c7/fineract-provider/src/main/java/org/apache/fineract/portfolio/collateral/service/CollateralWritePlatformServiceJpaRepositoryImpl.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/collateral/service/CollateralWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/collateral/service/CollateralWritePlatformServiceJpaRepositoryImpl.java
index f799f21..e57700a 100755
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/collateral/service/CollateralWritePlatformServiceJpaRepositoryImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/collateral/service/CollateralWritePlatformServiceJpaRepositoryImpl.java
@@ -33,16 +33,15 @@ import org.apache.fineract.portfolio.collateral.command.CollateralCommand;
 import org.apache.fineract.portfolio.collateral.domain.LoanCollateral;
 import org.apache.fineract.portfolio.collateral.domain.LoanCollateralRepository;
 import org.apache.fineract.portfolio.collateral.exception.CollateralCannotBeCreatedException;
-import org.apache.fineract.portfolio.collateral.exception.CollateralCannotBeDeletedException;
-import org.apache.fineract.portfolio.collateral.exception.CollateralCannotBeUpdatedException;
-import org.apache.fineract.portfolio.collateral.exception.CollateralNotFoundException;
 import org.apache.fineract.portfolio.collateral.exception.CollateralCannotBeCreatedException.LOAN_COLLATERAL_CANNOT_BE_CREATED_REASON;
+import org.apache.fineract.portfolio.collateral.exception.CollateralCannotBeDeletedException;
 import org.apache.fineract.portfolio.collateral.exception.CollateralCannotBeDeletedException.LOAN_COLLATERAL_CANNOT_BE_DELETED_REASON;
+import org.apache.fineract.portfolio.collateral.exception.CollateralCannotBeUpdatedException;
 import org.apache.fineract.portfolio.collateral.exception.CollateralCannotBeUpdatedException.LOAN_COLLATERAL_CANNOT_BE_UPDATED_REASON;
+import org.apache.fineract.portfolio.collateral.exception.CollateralNotFoundException;
 import org.apache.fineract.portfolio.collateral.serialization.CollateralCommandFromApiJsonDeserializer;
 import org.apache.fineract.portfolio.loanaccount.domain.Loan;
-import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository;
-import org.apache.fineract.portfolio.loanaccount.exception.LoanNotFoundException;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -56,17 +55,17 @@ public class CollateralWritePlatformServiceJpaRepositoryImpl implements Collater
     private final static Logger logger = LoggerFactory.getLogger(CollateralWritePlatformServiceJpaRepositoryImpl.class);
 
     private final PlatformSecurityContext context;
-    private final LoanRepository loanRepository;
+    private final LoanRepositoryWrapper loanRepositoryWrapper;
     private final LoanCollateralRepository collateralRepository;
     private final CodeValueRepositoryWrapper codeValueRepository;
     private final CollateralCommandFromApiJsonDeserializer collateralCommandFromApiJsonDeserializer;
 
     @Autowired
-    public CollateralWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final LoanRepository loanRepository,
+    public CollateralWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final LoanRepositoryWrapper loanRepositoryWrapper,
             final LoanCollateralRepository collateralRepository, final CodeValueRepositoryWrapper codeValueRepository,
             final CollateralCommandFromApiJsonDeserializer collateralCommandFromApiJsonDeserializer) {
         this.context = context;
-        this.loanRepository = loanRepository;
+        this.loanRepositoryWrapper = loanRepositoryWrapper;
         this.collateralRepository = collateralRepository;
         this.codeValueRepository = codeValueRepository;
         this.collateralCommandFromApiJsonDeserializer = collateralCommandFromApiJsonDeserializer;
@@ -81,9 +80,7 @@ public class CollateralWritePlatformServiceJpaRepositoryImpl implements Collater
         collateralCommand.validateForCreate();
 
         try {
-            final Loan loan = this.loanRepository.findOne(loanId);
-            if (loan == null) { throw new LoanNotFoundException(loanId); }
-
+            final Loan loan = this.loanRepositoryWrapper.findOneWithNotFoundDetection(loanId, true);
             final CodeValue collateralType = this.codeValueRepository.findOneByCodeNameAndIdWithNotFoundDetection(
                     CollateralApiConstants.COLLATERAL_CODE_NAME, collateralCommand.getCollateralTypeId());
             final LoanCollateral collateral = LoanCollateral.fromJson(loan, collateralType, command);
@@ -118,9 +115,7 @@ public class CollateralWritePlatformServiceJpaRepositoryImpl implements Collater
 
         final Long collateralTypeId = collateralCommand.getCollateralTypeId();
         try {
-            final Loan loan = this.loanRepository.findOne(loanId);
-            if (loan == null) { throw new LoanNotFoundException(loanId); }
-
+            final Loan loan = this.loanRepositoryWrapper.findOneWithNotFoundDetection(loanId, true);
             CodeValue collateralType = null;
 
             final LoanCollateral collateralForUpdate = this.collateralRepository.findOne(collateralId);
@@ -161,8 +156,7 @@ public class CollateralWritePlatformServiceJpaRepositoryImpl implements Collater
     @Transactional
     @Override
     public CommandProcessingResult deleteCollateral(final Long loanId, final Long collateralId, final Long commandId) {
-        final Loan loan = this.loanRepository.findOne(loanId);
-        if (loan == null) { throw new LoanNotFoundException(loanId); }
+        final Loan loan = this.loanRepositoryWrapper.findOneWithNotFoundDetection(loanId, true) ;
         final LoanCollateral collateral = this.collateralRepository.findByLoanIdAndId(loanId, collateralId);
         if (collateral == null) { throw new CollateralNotFoundException(loanId, collateralId); }
 
@@ -173,9 +167,7 @@ public class CollateralWritePlatformServiceJpaRepositoryImpl implements Collater
         if (!loan.status().isSubmittedAndPendingApproval()) { throw new CollateralCannotBeDeletedException(
                 LOAN_COLLATERAL_CANNOT_BE_DELETED_REASON.LOAN_NOT_IN_SUBMITTED_AND_PENDING_APPROVAL_STAGE, loanId, collateralId); }
 
-        loan.getCollateral().remove(collateral);
         this.collateralRepository.delete(collateral);
-
         return new CommandProcessingResultBuilder().withCommandId(commandId).withLoanId(loanId).withEntityId(collateralId).build();
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/025ff9c7/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/service/GroupingTypesWritePlatformServiceJpaRepositoryImpl.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/service/GroupingTypesWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/service/GroupingTypesWritePlatformServiceJpaRepositoryImpl.java
index aa65886..1aa8b5c 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/service/GroupingTypesWritePlatformServiceJpaRepositoryImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/group/service/GroupingTypesWritePlatformServiceJpaRepositoryImpl.java
@@ -42,9 +42,8 @@ import org.apache.fineract.infrastructure.core.exception.GeneralPlatformDomainRu
 import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
 import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
 import org.apache.fineract.organisation.office.domain.Office;
-import org.apache.fineract.organisation.office.domain.OfficeRepository;
+import org.apache.fineract.organisation.office.domain.OfficeRepositoryWrapper;
 import org.apache.fineract.organisation.office.exception.InvalidOfficeException;
-import org.apache.fineract.organisation.office.exception.OfficeNotFoundException;
 import org.apache.fineract.organisation.staff.domain.Staff;
 import org.apache.fineract.organisation.staff.domain.StaffRepositoryWrapper;
 import org.apache.fineract.portfolio.calendar.domain.Calendar;
@@ -70,12 +69,11 @@ import org.apache.fineract.portfolio.group.exception.InvalidGroupLevelException;
 import org.apache.fineract.portfolio.group.exception.InvalidGroupStateTransitionException;
 import org.apache.fineract.portfolio.group.serialization.GroupingTypesDataValidator;
 import org.apache.fineract.portfolio.loanaccount.domain.Loan;
-import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository;
 import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper;
 import org.apache.fineract.portfolio.note.domain.Note;
 import org.apache.fineract.portfolio.note.domain.NoteRepository;
 import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
-import org.apache.fineract.portfolio.savings.domain.SavingsAccountRepository;
+import org.apache.fineract.portfolio.savings.domain.SavingsAccountRepositoryWrapper;
 import org.apache.fineract.useradministration.domain.AppUser;
 import org.joda.time.LocalDate;
 import org.slf4j.Logger;
@@ -95,47 +93,43 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
     private final PlatformSecurityContext context;
     private final GroupRepositoryWrapper groupRepository;
     private final ClientRepositoryWrapper clientRepositoryWrapper;
-    private final OfficeRepository officeRepository;
+    private final OfficeRepositoryWrapper officeRepositoryWrapper;
     private final StaffRepositoryWrapper staffRepository;
     private final NoteRepository noteRepository;
     private final GroupLevelRepository groupLevelRepository;
     private final GroupingTypesDataValidator fromApiJsonDeserializer;
-    private final LoanRepository loanRepository;
+    private final LoanRepositoryWrapper loanRepositoryWrapper;
     private final CodeValueRepositoryWrapper codeValueRepository;
-    private final SavingsAccountRepository savingsRepository;
     private final CommandProcessingService commandProcessingService;
     private final CalendarInstanceRepository calendarInstanceRepository;
     private final ConfigurationDomainService configurationDomainService;
-    private final SavingsAccountRepository savingsAccountRepository;
-    private final LoanRepositoryWrapper loanRepositoryWrapper;
+    private final SavingsAccountRepositoryWrapper savingsAccountRepositoryWrapper;
     private final AccountNumberFormatRepositoryWrapper accountNumberFormatRepository;
     private final AccountNumberGenerator accountNumberGenerator;
 
     @Autowired
     public GroupingTypesWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
             final GroupRepositoryWrapper groupRepository, final ClientRepositoryWrapper clientRepositoryWrapper,
-            final OfficeRepository officeRepository, final StaffRepositoryWrapper staffRepository, final NoteRepository noteRepository,
+            final OfficeRepositoryWrapper officeRepositoryWrapper, final StaffRepositoryWrapper staffRepository, final NoteRepository noteRepository,
             final GroupLevelRepository groupLevelRepository, final GroupingTypesDataValidator fromApiJsonDeserializer,
-            final LoanRepository loanRepository, final SavingsAccountRepository savingsRepository,
+            final SavingsAccountRepositoryWrapper savingsAccountRepositoryWrapper,
             final CodeValueRepositoryWrapper codeValueRepository, final CommandProcessingService commandProcessingService,
             final CalendarInstanceRepository calendarInstanceRepository, final ConfigurationDomainService configurationDomainService,
-            final SavingsAccountRepository savingsAccountRepository, final LoanRepositoryWrapper loanRepositoryWrapper, 
+            final LoanRepositoryWrapper loanRepositoryWrapper, 
             final AccountNumberFormatRepositoryWrapper accountNumberFormatRepository, final AccountNumberGenerator accountNumberGenerator) {
         this.context = context;
         this.groupRepository = groupRepository;
         this.clientRepositoryWrapper = clientRepositoryWrapper;
-        this.officeRepository = officeRepository;
+        this.officeRepositoryWrapper = officeRepositoryWrapper;
         this.staffRepository = staffRepository;
         this.noteRepository = noteRepository;
         this.groupLevelRepository = groupLevelRepository;
         this.fromApiJsonDeserializer = fromApiJsonDeserializer;
-        this.loanRepository = loanRepository;
-        this.savingsRepository = savingsRepository;
+        this.savingsAccountRepositoryWrapper = savingsAccountRepositoryWrapper;
         this.codeValueRepository = codeValueRepository;
         this.commandProcessingService = commandProcessingService;
         this.calendarInstanceRepository = calendarInstanceRepository;
         this.configurationDomainService = configurationDomainService;
-        this.savingsAccountRepository = savingsAccountRepository;
         this.loanRepositoryWrapper = loanRepositoryWrapper;
         this.accountNumberFormatRepository = accountNumberFormatRepository;
         this.accountNumberGenerator = accountNumberGenerator;
@@ -158,8 +152,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
                 officeId = parentGroup.officeId();
             }
 
-            final Office groupOffice = this.officeRepository.findOne(officeId);
-            if (groupOffice == null) { throw new OfficeNotFoundException(officeId); }
+            final Office groupOffice = this.officeRepositoryWrapper.findOneWithNotFoundDetection(officeId);
 
             final LocalDate activationDate = command.localDateValueOfParameterNamed(GroupingTypesApiConstants.activationDateParamName);
             final GroupLevel groupLevel = this.groupLevelRepository.findOne(groupingType.getId());
@@ -506,15 +499,15 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
             if (clients != null) {
                 for (Client client : clients) {
                     client.updateStaff(staff);
-                    if (this.loanRepository.doNonClosedLoanAccountsExistForClient(client.getId())) {
-                        for (final Loan loan : this.loanRepository.findLoanByClientId(client.getId())) {
+                    if (this.loanRepositoryWrapper.doNonClosedLoanAccountsExistForClient(client.getId())) {
+                        for (final Loan loan : this.loanRepositoryWrapper.findLoanByClientId(client.getId())) {
                             if (loan.isDisbursed() && !loan.isClosed()) {
                                 loan.reassignLoanOfficer(staff, loanOfficerReassignmentDate);
                             }
                         }
                     }
-                    if (this.savingsAccountRepository.doNonClosedSavingAccountsExistForClient(client.getId())) {
-                        for (final SavingsAccount savingsAccount : this.savingsAccountRepository
+                    if (this.savingsAccountRepositoryWrapper.doNonClosedSavingAccountsExistForClient(client.getId())) {
+                        for (final SavingsAccount savingsAccount : this.savingsAccountRepositoryWrapper
                                 .findSavingAccountByClientId(client.getId())) {
                             if (!savingsAccount.isClosed()) {
                                 savingsAccount.reassignSavingsOfficer(staff, loanOfficerReassignmentDate);
@@ -588,7 +581,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
     }
 
     private void validateLoansAndSavingsForGroupOrCenterClose(final Group groupOrCenter, final LocalDate closureDate) {
-        final Collection<Loan> groupLoans = this.loanRepository.findByGroupId(groupOrCenter.getId());
+        final Collection<Loan> groupLoans = this.loanRepositoryWrapper.findByGroupId(groupOrCenter.getId());
         for (final Loan loan : groupLoans) {
             final LoanStatusMapper loanStatus = new LoanStatusMapper(loan.status().getValue());
             if (loanStatus.isOpen()) {
@@ -611,7 +604,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
             }
         }
 
-        final List<SavingsAccount> groupSavingAccounts = this.savingsRepository.findByGroupId(groupOrCenter.getId());
+        final List<SavingsAccount> groupSavingAccounts = this.savingsAccountRepositoryWrapper.findByGroupId(groupOrCenter.getId());
 
         for (final SavingsAccount saving : groupSavingAccounts) {
             if (saving.isActive() || saving.isSubmittedAndPendingApproval() || saving.isApproved()) {
@@ -871,7 +864,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
     @Transactional
     private void validateForJLGSavings(final Long groupId, final Set<Client> clientMembers) {
         for (final Client client : clientMembers) {
-            final Collection<SavingsAccount> savings = this.savingsRepository.findByClientIdAndGroupId(client.getId(), groupId);
+            final Collection<SavingsAccount> savings = this.savingsAccountRepositoryWrapper.findByClientIdAndGroupId(client.getId(), groupId);
             if (!CollectionUtils.isEmpty(savings)) {
                 final String defaultUserMessage = "Client with identifier " + client.getId()
                         + " cannot be disassociated it has group savings.";

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/025ff9c7/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
index 98422fb..5a43e29 100755
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
@@ -245,10 +245,10 @@ public class Loan extends AbstractPersistable<Long> {
     @Column(name = "loan_product_counter")
     private Integer loanProductCounter;
 
-    @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true, fetch=FetchType.EAGER)
+    @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true, fetch=FetchType.LAZY)
     private Set<LoanCharge> charges = new HashSet<>();
 
-    @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true, fetch=FetchType.EAGER)
+    @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true, fetch=FetchType.LAZY)
     private Set<LoanTrancheCharge> trancheCharges = new HashSet<>();
 
     @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true, fetch=FetchType.LAZY)
@@ -257,26 +257,14 @@ public class Loan extends AbstractPersistable<Long> {
     @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true, fetch=FetchType.LAZY)
     private Set<LoanOfficerAssignmentHistory> loanOfficerHistory;
 
-    // see
-    // http://stackoverflow.com/questions/4334970/hibernate-cannot-simultaneously-fetch-multiple-bags
     @OrderBy(value = "installmentNumber")
-    @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true, fetch=FetchType.EAGER)
-    private final Set<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments = new HashSet<>();
+    @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true, fetch=FetchType.LAZY)
+    private final List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments = new ArrayList<>();
 
-    // see
-    // http://stackoverflow.com/questions/4334970/hibernate-cannot-simultaneously-fetch-multiple-bags
     @OrderBy(value = "dateOf, id")
-    @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true, fetch=FetchType.EAGER)
-    private final Set<LoanTransaction> loanTransactions = new HashSet<>();
+    @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true, fetch=FetchType.LAZY)
+    private final List<LoanTransaction> loanTransactions = new ArrayList<>();
 
-    private transient List<LoanTransaction> sortedTransactions = null ;
-    
-    private transient boolean isTransactionsListDirty = false ;
-    
-    private transient List<LoanRepaymentScheduleInstallment> sortedrepaymentScheduleInstallments = null ;
-    
-    private transient boolean isrepaymentScheduleInstallmentsListDirty = false ;
-    
     @Embedded
     private LoanSummary summary;
 
@@ -302,13 +290,13 @@ public class Loan extends AbstractPersistable<Long> {
     @Column(name = "max_outstanding_loan_balance", scale = 6, precision = 19, nullable = false)
     private BigDecimal maxOutstandingLoanBalance;
 
-    @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true, fetch=FetchType.EAGER)
+    @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true, fetch=FetchType.LAZY)
     @OrderBy(value = "expectedDisbursementDate, id")
-    private Set<LoanDisbursementDetails> disbursementDetails = new HashSet<>();
+    private List<LoanDisbursementDetails> disbursementDetails = new ArrayList<>();
 
     @OrderBy(value = "termApplicableFrom, id")
-    @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true, fetch=FetchType.EAGER)
-    private final Set<LoanTermVariations> loanTermVariations = new HashSet<>();
+    @OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true, fetch=FetchType.LAZY)
+    private final List<LoanTermVariations> loanTermVariations = new ArrayList<>();
 
     @Column(name = "total_recovered_derived", scale = 6, precision = 19)
     private BigDecimal totalRecovered;
@@ -349,8 +337,6 @@ public class Loan extends AbstractPersistable<Long> {
     @Column(name = "is_topup", nullable = false)
     private boolean isTopup = false;
 
-//    @OneToOne(cascade = CascadeType.ALL,  orphanRemoval = true, fetch=FetchType.EAGER)
-//    @JoinColumn(name = "loan_id", referencedColumnName= "id" , nullable = true)
     @OneToOne(cascade = CascadeType.ALL, mappedBy = "loan", optional = true, orphanRemoval = true, fetch=FetchType.EAGER)
     private LoanTopupDetails loanTopupDetails;
 
@@ -358,7 +344,7 @@ public class Loan extends AbstractPersistable<Long> {
             final LoanProduct loanProduct, final Fund fund, final Staff officer, final CodeValue loanPurpose,
             final LoanTransactionProcessingStrategy transactionProcessingStrategy,
             final LoanProductRelatedDetail loanRepaymentScheduleDetail, final Set<LoanCharge> loanCharges,
-            final Set<LoanCollateral> collateral, final BigDecimal fixedEmiAmount, final Set<LoanDisbursementDetails> disbursementDetails,
+            final Set<LoanCollateral> collateral, final BigDecimal fixedEmiAmount, final List<LoanDisbursementDetails> disbursementDetails,
             final BigDecimal maxOutstandingLoanBalance, final Boolean createStandingInstructionAtDisbursement,
             final Boolean isFloatingInterestRate, final BigDecimal interestRateDifferential) {
         final LoanStatus status = null;
@@ -375,7 +361,7 @@ public class Loan extends AbstractPersistable<Long> {
             final LoanTransactionProcessingStrategy transactionProcessingStrategy,
             final LoanProductRelatedDetail loanRepaymentScheduleDetail, final Set<LoanCharge> loanCharges,
             final Set<LoanCollateral> collateral, final Boolean syncDisbursementWithMeeting, final BigDecimal fixedEmiAmount,
-            final Set<LoanDisbursementDetails> disbursementDetails, final BigDecimal maxOutstandingLoanBalance,
+            final List<LoanDisbursementDetails> disbursementDetails, final BigDecimal maxOutstandingLoanBalance,
             final Boolean createStandingInstructionAtDisbursement, final Boolean isFloatingInterestRate,
             final BigDecimal interestRateDifferential) {
         final LoanStatus status = null;
@@ -391,7 +377,7 @@ public class Loan extends AbstractPersistable<Long> {
             final LoanTransactionProcessingStrategy transactionProcessingStrategy,
             final LoanProductRelatedDetail loanRepaymentScheduleDetail, final Set<LoanCharge> loanCharges,
             final Set<LoanCollateral> collateral, final Boolean syncDisbursementWithMeeting, final BigDecimal fixedEmiAmount,
-            final Set<LoanDisbursementDetails> disbursementDetails, final BigDecimal maxOutstandingLoanBalance,
+            final List<LoanDisbursementDetails> disbursementDetails, final BigDecimal maxOutstandingLoanBalance,
             final Boolean createStandingInstructionAtDisbursement, final Boolean isFloatingInterestRate,
             final BigDecimal interestRateDifferential) {
         final LoanStatus status = null;
@@ -409,7 +395,7 @@ public class Loan extends AbstractPersistable<Long> {
             final Staff loanOfficer, final CodeValue loanPurpose, final LoanTransactionProcessingStrategy transactionProcessingStrategy,
             final LoanProduct loanProduct, final LoanProductRelatedDetail loanRepaymentScheduleDetail, final LoanStatus loanStatus,
             final Set<LoanCharge> loanCharges, final Set<LoanCollateral> collateral, final Boolean syncDisbursementWithMeeting,
-            final BigDecimal fixedEmiAmount, final Set<LoanDisbursementDetails> disbursementDetails,
+            final BigDecimal fixedEmiAmount, final List<LoanDisbursementDetails> disbursementDetails,
             final BigDecimal maxOutstandingLoanBalance, final Boolean createStandingInstructionAtDisbursement,
             final Boolean isFloatingInterestRate, final BigDecimal interestRateDifferential) {
 
@@ -587,7 +573,6 @@ public class Loan extends AbstractPersistable<Long> {
             mapEntry.getValue().updateLoan(this);
         }
         this.loanTransactions.addAll(changedTransactionDetail.getNewTransactionMappings().values());
-        this.isTransactionsListDirty = true ;
         updateLoanSummaryDerivedFields();
         this.loanTransactions.removeAll(changedTransactionDetail.getNewTransactionMappings().values());
         return changedTransactionDetail;
@@ -1098,7 +1083,6 @@ public class Loan extends AbstractPersistable<Long> {
 
     public void updateLoanSchedule(final LoanScheduleModel modifiedLoanSchedule, AppUser currentUser) {
         this.repaymentScheduleInstallments.clear();
-        this.isrepaymentScheduleInstallmentsListDirty = true ;
         for (final LoanScheduleModelPeriod scheduledLoanInstallment : modifiedLoanSchedule.getPeriods()) {
 
             if (scheduledLoanInstallment.isRepaymentPeriod()) {
@@ -1120,7 +1104,6 @@ public class Loan extends AbstractPersistable<Long> {
 
     public void updateLoanSchedule(final Collection<LoanRepaymentScheduleInstallment> installments, AppUser currentUser) {
         this.repaymentScheduleInstallments.clear();
-        this.isrepaymentScheduleInstallmentsListDirty = true ;
         for (final LoanRepaymentScheduleInstallment installment : installments) {
             addLoanRepaymentScheduleInstallment(installment);
         }
@@ -1848,8 +1831,7 @@ public class Loan extends AbstractPersistable<Long> {
         List<LoanTransaction> transactions = getLoanTransactions() ;
         for (final LoanTransaction loanTransaction : transactions) {
             if (loanTransaction.isDisbursement()) {
-                this.loanTransactions.remove(loanTransaction);
-                transactions.remove(loanTransaction) ;
+                removeLoanTransaction(loanTransaction);
                 break;
             }
         }
@@ -2201,7 +2183,6 @@ public class Loan extends AbstractPersistable<Long> {
     }
 
     public Collection<Long> findExistingTransactionIds() {
-
         final Collection<Long> ids = new ArrayList<>();
         List<LoanTransaction> transactions = getLoanTransactions() ;
         for (final LoanTransaction transaction : transactions) {
@@ -2749,7 +2730,6 @@ public class Loan extends AbstractPersistable<Long> {
             }
         }
         this.loanTransactions.retainAll(retainTransactions);
-        isTransactionsListDirty = true ;
     }
 
     private void updateLoanToPreDisbursalState() {
@@ -3008,7 +2988,6 @@ public class Loan extends AbstractPersistable<Long> {
              * transactions first and then new transactions.
              */
             this.loanTransactions.addAll(changedTransactionDetail.getNewTransactionMappings().values());
-            this.isTransactionsListDirty = true ;
         }
 
         updateLoanSummaryDerivedFields();
@@ -4478,17 +4457,15 @@ public class Loan extends AbstractPersistable<Long> {
 
     //This method returns copy of all transactions
     public List<LoanTransaction> getLoanTransactions() {
-        if(this.sortedTransactions == null || isTransactionsListDirty) {
-            this.sortedTransactions = new ArrayList<>(this.loanTransactions) ;
-            this.sortedTransactions.sort(new LoanTransactionComparator());
-            this.isTransactionsListDirty = false ;
-        }
-        return sortedTransactions;
+        return this.loanTransactions;
     }
 
     public void addLoanTransaction(final LoanTransaction loanTransaction) {
         this.loanTransactions.add(loanTransaction) ;
-        this.isTransactionsListDirty = true ;
+    }
+    
+    public void removeLoanTransaction(final LoanTransaction loanTransaction) {
+        this.loanTransactions.remove(loanTransaction) ;
     }
     
     public void setLoanStatus(final Integer loanStatus) {
@@ -4859,7 +4836,7 @@ public class Loan extends AbstractPersistable<Long> {
         return list;
     }
 
-    public Set<LoanDisbursementDetails> getDisbursementDetails() {
+    public List<LoanDisbursementDetails> getDisbursementDetails() {
         return this.disbursementDetails;
     }
 
@@ -5017,7 +4994,6 @@ public class Loan extends AbstractPersistable<Long> {
          * first and then new transactions.
          */
         this.loanTransactions.addAll(changedTransactionDetail.getNewTransactionMappings().values());
-        this.isTransactionsListDirty = true ;
         updateLoanSummaryDerivedFields();
 
         this.loanTransactions.removeAll(changedTransactionDetail.getNewTransactionMappings().values());
@@ -5430,11 +5406,7 @@ public class Loan extends AbstractPersistable<Long> {
      * @return List of loan repayments schedule objects
      **/
     public List<LoanRepaymentScheduleInstallment> getRepaymentScheduleInstallments() {
-        if (this.sortedrepaymentScheduleInstallments == null || this.isrepaymentScheduleInstallmentsListDirty) {
-            this.sortedrepaymentScheduleInstallments = new ArrayList<>(this.repaymentScheduleInstallments);
-            this.sortedrepaymentScheduleInstallments.sort(LoanRepaymentScheduleInstallment.installmentNumberComparator);
-        }
-        return sortedrepaymentScheduleInstallments;
+        return this.repaymentScheduleInstallments;
     }
 
     public Integer getLoanRepaymentScheduleInstallmentsSize() {
@@ -5443,7 +5415,6 @@ public class Loan extends AbstractPersistable<Long> {
     public void addLoanRepaymentScheduleInstallment(final LoanRepaymentScheduleInstallment installment) {
         installment.updateLoan(this);
         this.repaymentScheduleInstallments.add(installment);
-        this.isrepaymentScheduleInstallmentsListDirty = true ;
     }
     /**
      * @return Loan product minimum repayments schedule related detail
@@ -5944,7 +5915,7 @@ public class Loan extends AbstractPersistable<Long> {
         this.interestRateDifferential = interestRateDifferential;
     }
 
-    public Set<LoanTermVariations> getLoanTermVariations() {
+    public List<LoanTermVariations> getLoanTermVariations() {
         return this.loanTermVariations;
     }
 
@@ -5982,7 +5953,7 @@ public class Loan extends AbstractPersistable<Long> {
      * get the next repayment date for rescheduling at the time of disbursement
      */
     public LocalDate getNextPossibleRepaymentDateForRescheduling() {
-        Set<LoanDisbursementDetails> loanDisbursementDetails = this.disbursementDetails;
+        List<LoanDisbursementDetails> loanDisbursementDetails = this.disbursementDetails;
         LocalDate nextRepaymentDate = new LocalDate();
         for (LoanDisbursementDetails loanDisbursementDetail : loanDisbursementDetails) {
             if (loanDisbursementDetail.actualDisbursementDate() == null) {
@@ -6367,4 +6338,27 @@ public class Loan extends AbstractPersistable<Long> {
     public Collection<LoanCharge> getLoanCharges() {
         return this.charges;
     }
+    
+    public void initializeLazyCollections() {
+        this.charges.size() ;
+        this.trancheCharges.size() ;
+        this.repaymentScheduleInstallments.size() ;
+        this.loanTransactions.size() ;
+        this.disbursementDetails.size() ;
+        this.loanTermVariations.size() ;
+        this.collateral.size() ;
+        this.loanOfficerHistory.size() ;
+    }
+    
+    public void initializeLoanOfficerHistory() {
+        this.loanOfficerHistory.size() ;
+    }
+    
+    public void initilizeTransactions() {
+        this.loanTransactions.size() ;
+    }
+    
+    public void initializeRepaymentSchedule() {
+        this.repaymentScheduleInstallments.size() ;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/025ff9c7/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java
index 58dc662..31f6a62 100755
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java
@@ -83,7 +83,7 @@ import org.springframework.transaction.annotation.Transactional;
 public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
 
     private final LoanAssembler loanAccountAssembler;
-    private final LoanRepository loanRepository;
+    private final LoanRepositoryWrapper loanRepositoryWrapper;
     private final LoanTransactionRepository loanTransactionRepository;
     private final ConfigurationDomainService configurationDomainService;
     private final HolidayRepository holidayRepository;
@@ -102,7 +102,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
     private final StandingInstructionRepository standingInstructionRepository;
 
     @Autowired
-    public LoanAccountDomainServiceJpa(final LoanAssembler loanAccountAssembler, final LoanRepository loanRepository,
+    public LoanAccountDomainServiceJpa(final LoanAssembler loanAccountAssembler, final LoanRepositoryWrapper loanRepositoryWrapper,
             final LoanTransactionRepository loanTransactionRepository, final NoteRepository noteRepository,
             final ConfigurationDomainService configurationDomainService, final HolidayRepository holidayRepository,
             final WorkingDaysRepositoryWrapper workingDaysRepository,
@@ -115,7 +115,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
             final BusinessEventNotifierService businessEventNotifierService, final LoanUtilService loanUtilService, 
             final StandingInstructionRepository standingInstructionRepository) {
         this.loanAccountAssembler = loanAccountAssembler;
-        this.loanRepository = loanRepository;
+        this.loanRepositoryWrapper = loanRepositoryWrapper;
         this.loanTransactionRepository = loanTransactionRepository;
         this.noteRepository = noteRepository;
         this.configurationDomainService = configurationDomainService;
@@ -260,7 +260,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
                     this.repaymentScheduleInstallmentRepository.save(installment);
                 }
             }
-            this.loanRepository.saveAndFlush(loan);
+            this.loanRepositoryWrapper.saveAndFlush(loan);
         } catch (final DataIntegrityViolationException e) {
             final Throwable realCause = e.getCause();
             final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
@@ -282,7 +282,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
                     this.repaymentScheduleInstallmentRepository.save(installment);
                 }
             }
-            this.loanRepository.save(loan);
+            this.loanRepositoryWrapper.save(loan);
         } catch (final DataIntegrityViolationException e) {
             final Throwable realCause = e.getCause();
             final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
@@ -403,7 +403,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
                 allowTransactionsOnHoliday, holidays, workingDays, allowTransactionsOnNonWorkingDay);
 
         saveLoanTransactionWithDataIntegrityViolationChecks(newRefundTransaction);
-        this.loanRepository.save(loan);
+        this.loanRepositoryWrapper.save(loan);
 
         if (StringUtils.isNotBlank(noteText)) {
             final Note note = Note.loanTransactionNote(loan, newRefundTransaction, noteText);
@@ -593,7 +593,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
                 existingReversedTransactionIds, allowTransactionsOnHoliday, holidays, workingDays, allowTransactionsOnNonWorkingDay);
 
         this.loanTransactionRepository.save(newRefundTransaction);
-        this.loanRepository.save(loan);
+        this.loanRepositoryWrapper.save(loan);
 
         if (StringUtils.isNotBlank(noteText)) {
             final Note note = Note.loanTransactionNote(loan, newRefundTransaction, noteText);
@@ -646,7 +646,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
                 }
                 createdDate = createdDate.plusSeconds(1);
                 newTransactions.add(accrualTransaction);
-                loan.getLoanTransactions().add(accrualTransaction);
+                loan.addLoanTransaction(accrualTransaction);
                 Set<LoanChargePaidBy> accrualCharges = accrualTransaction.getLoanChargesPaid();
                 for (LoanCharge loanCharge : loan.charges()) {
                     if (loanCharge.isActive()

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/025ff9c7/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepositoryWrapper.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepositoryWrapper.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepositoryWrapper.java
index f2438b7..9a32523 100755
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepositoryWrapper.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepositoryWrapper.java
@@ -21,10 +21,14 @@ package org.apache.fineract.portfolio.loanaccount.domain;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Date;
+import java.util.List;
 
 import org.apache.fineract.portfolio.loanaccount.exception.LoanNotFoundException;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.repository.query.Param;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 /**
  * <p>
@@ -43,11 +47,20 @@ public class LoanRepositoryWrapper {
     }
 
     public Loan findOneWithNotFoundDetection(final Long id) {
+        return this.findOneWithNotFoundDetection(id, false) ;
+    }
+
+    @Transactional(readOnly=true)
+    public Loan findOneWithNotFoundDetection(final Long id, boolean loadLazyCollections) {
         final Loan loan = this.repository.findOne(id);
         if (loan == null) { throw new LoanNotFoundException(id); }
+        if(loadLazyCollections) {
+            loan.initializeLazyCollections();
+        }
         return loan;
     }
-
+    
+    //Root Entities are enough
     public Collection<Loan> findActiveLoansByLoanIdAndGroupId(Long clientId, Long groupId) {
         final Collection<Integer> loanStatuses = new ArrayList<>(Arrays.asList(LoanStatus.SUBMITTED_AND_PENDING_APPROVAL.getValue(),
                 LoanStatus.APPROVED.getValue(), LoanStatus.ACTIVE.getValue(), LoanStatus.OVERPAID.getValue()));
@@ -55,4 +68,170 @@ public class LoanRepositoryWrapper {
         return loans;
     }
 
+    public Loan saveAndFlush(final Loan loan) {
+        return this.repository.saveAndFlush(loan) ;
+    }
+    
+    public Loan save(final Loan loan) {
+        return this.repository.save(loan) ;
+    }
+    
+    public List<Loan> save(List<Loan> loans) {
+        return this.repository.save(loans) ;
+    }
+    public void flush() {
+        this.repository.flush(); 
+    }
+    
+    public void delete(final Long loanId) {
+        this.repository.delete(loanId);
+    }
+    //Only root entities is enough
+    public List<Loan> getGroupLoansDisbursedAfter(@Param("disbursementDate") Date disbursementDate, @Param("groupId") Long groupId,
+            @Param("loanType") Integer loanType) {
+        return this.repository.getGroupLoansDisbursedAfter(disbursementDate, groupId, loanType) ;
+    }
+    //Only root entities enough
+    public List<Loan> getClientOrJLGLoansDisbursedAfter(@Param("disbursementDate") Date disbursementDate, @Param("clientId") Long clientId) {
+        return this.repository.getClientOrJLGLoansDisbursedAfter(disbursementDate, clientId) ;
+    }
+
+    public Integer getMaxGroupLoanCounter(@Param("groupId") Long groupId, @Param("loanType") Integer loanType) {
+        return this.repository.getMaxGroupLoanCounter(groupId, loanType) ;
+    }
+
+    public Integer getMaxGroupLoanProductCounter(@Param("productId") Long productId, @Param("groupId") Long groupId,
+            @Param("loanType") Integer loanType) {
+        return this.repository.getMaxGroupLoanProductCounter(productId, groupId, loanType) ;
+    }
+
+    public Integer getMaxClientOrJLGLoanCounter(@Param("clientId") Long clientId) {
+        return this.repository.getMaxClientOrJLGLoanCounter(clientId) ;
+    }
+
+    public Integer getMaxClientOrJLGLoanProductCounter(@Param("productId") Long productId, @Param("clientId") Long clientId) {
+        return this.repository.getMaxClientOrJLGLoanProductCounter(productId, clientId) ;
+    }
+
+    //Only root entities are enough
+    public List<Loan> getGroupLoansToUpdateLoanCounter(@Param("loanCounter") Integer loanCounter, @Param("groupId") Long groupId,
+            @Param("groupLoanType") Integer groupLoanType) {
+        return this.repository.getGroupLoansToUpdateLoanCounter(loanCounter, groupId, groupLoanType) ;
+    }
+
+    //Only root entities are enough
+    public List<Loan> getClientOrJLGLoansToUpdateLoanCounter(@Param("loanCounter") Integer loanCounter, @Param("clientId") Long clientId) {
+        return this.repository.getClientOrJLGLoansToUpdateLoanCounter(loanCounter, clientId) ;
+    }
+
+    //Only root entities are enough
+    public List<Loan> getGroupLoansToUpdateLoanProductCounter(@Param("loanProductCounter") Integer loanProductCounter,
+            @Param("groupId") Long groupId, @Param("groupLoanType") Integer groupLoanType) {
+        return this.repository.getGroupLoansToUpdateLoanProductCounter(loanProductCounter, groupId, groupLoanType) ;
+    }
+    
+    //Only root entities are enough
+    public List<Loan> getClientLoansToUpdateLoanProductCounter(@Param("loanProductCounter") Integer loanProductCounter,
+            @Param("clientId") Long clientId) {
+        return this.repository.getClientLoansToUpdateLoanProductCounter(loanProductCounter, clientId) ;
+    }
+
+    //Need loanOfficerHistory. Check whether FETCH JOIN is good enough here
+    @Transactional(readOnly=true)
+    public List<Loan> findByClientIdAndGroupId(@Param("clientId") Long clientId, @Param("groupId") Long groupId) {
+        List<Loan> loans = this.repository.findByClientIdAndGroupId(clientId, groupId) ;
+        if(loans != null && loans.size() > 0) {
+            for(Loan loan: loans) {
+                loan.initializeLoanOfficerHistory();
+            }
+        }
+        return loans ;
+    }
+
+    //need loanTransactions, loanOfficerHistory
+    @Transactional(readOnly=true)
+    public List<Loan> findLoanByClientId(@Param("clientId") Long clientId) {
+        List<Loan> loans = this.repository.findLoanByClientId(clientId) ;
+        if(loans != null && loans.size() > 0) {
+            for(Loan loan: loans) {
+                loan.initilizeTransactions();
+                loan.initializeLoanOfficerHistory();
+            }
+        }
+        return loans ;
+    }
+
+    //Root entities are enough
+    public List<Loan> findByGroupId(@Param("groupId") Long groupId) {
+        return this.repository.findByGroupId(groupId) ;
+    }
+
+    //Looks like we need complete Data
+    public List<Loan> findByIdsAndLoanStatusAndLoanType(@Param("ids") Collection<Long> ids,
+            @Param("loanStatuses") Collection<Integer> loanStatuses, @Param("loanTypes") Collection<Integer> loanTypes) {
+        List<Loan> loans =this.repository.findByIdsAndLoanStatusAndLoanType(ids, loanStatuses, loanTypes) ;
+        if(loans != null && loans.size() > 0) {
+            for(Loan loan: loans) {
+                loan.initializeLazyCollections();
+            }
+        }
+        return loans ;
+    }
+
+    //This method is not used
+    public List<Long> getLoansDisbursedAfter(@Param("disbursalDate") Date disbursalDate) {
+        return this.repository.getLoansDisbursedAfter(disbursalDate) ;
+    }
+
+    //Repayments Schedule
+    public List<Loan> findByClientOfficeIdsAndLoanStatus(@Param("officeIds") Collection<Long> officeIds,
+            @Param("loanStatuses") Collection<Integer> loanStatuses) {
+        List<Loan> loans = this.repository.findByClientOfficeIdsAndLoanStatus(officeIds, loanStatuses) ;
+        if(loans != null && loans.size() >0) {
+            for(Loan loan: loans) {
+                loan.initializeRepaymentSchedule();
+            }
+        }
+        return loans ; 
+    }
+
+  //Repayments Schedule
+    public List<Loan> findByGroupOfficeIdsAndLoanStatus(@Param("officeIds") Collection<Long> officeIds,
+            @Param("loanStatuses") Collection<Integer> loanStatuses) {
+        List<Loan> loans = this.repository.findByGroupOfficeIdsAndLoanStatus(officeIds, loanStatuses) ;
+        if(loans != null && loans.size() >0) {
+            for(Loan loan: loans) {
+                loan.initializeRepaymentSchedule();
+            }
+        }
+        return loans ; 
+    }
+
+    public List<Long> findActiveLoansLoanProductIdsByClient(@Param("clientId") Long clientId, @Param("loanStatus") Integer loanStatus) {
+        return this.repository.findActiveLoansLoanProductIdsByClient(clientId, loanStatus) ;
+    }
+
+    public List<Long> findActiveLoansLoanProductIdsByGroup(@Param("groupId") Long groupId, @Param("loanStatus") Integer loanStatus) {
+        return this.repository.findActiveLoansLoanProductIdsByGroup(groupId, loanStatus) ;
+    }
+
+    public boolean doNonClosedLoanAccountsExistForClient(@Param("clientId") Long clientId) {
+        return this.repository.doNonClosedLoanAccountsExistForClient(clientId) ;
+    }
+    
+    public boolean doNonClosedLoanAccountsExistForProduct(@Param("productId") Long productId) {
+        return this.repository.doNonClosedLoanAccountsExistForProduct(productId) ;
+    }
+    
+    public Loan findNonClosedLoanByAccountNumber(@Param("accountNumber") String accountNumber) {
+        return this.repository.findNonClosedLoanByAccountNumber(accountNumber) ;
+    }
+
+    //Looks like we need complete entity
+    @Transactional(readOnly=true)
+    public Loan findNonClosedLoanThatBelongsToClient(@Param("loanId") Long loanId, @Param("clientId") Long clientId) {
+        Loan loan = this.repository.findNonClosedLoanThatBelongsToClient(loanId, clientId) ;
+        if(loan != null) loan.initilizeTransactions();
+        return loan ;
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/025ff9c7/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/service/GuarantorReadPlatformServiceImpl.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/service/GuarantorReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/service/GuarantorReadPlatformServiceImpl.java
index 38b884e..e5dc0f5 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/service/GuarantorReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/service/GuarantorReadPlatformServiceImpl.java
@@ -35,9 +35,7 @@ import org.apache.fineract.portfolio.account.data.PortfolioAccountData;
 import org.apache.fineract.portfolio.account.domain.AccountAssociationType;
 import org.apache.fineract.portfolio.client.data.ClientData;
 import org.apache.fineract.portfolio.client.service.ClientReadPlatformService;
-import org.apache.fineract.portfolio.loanaccount.domain.Loan;
-import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository;
-import org.apache.fineract.portfolio.loanaccount.exception.LoanNotFoundException;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper;
 import org.apache.fineract.portfolio.loanaccount.guarantor.data.GuarantorData;
 import org.apache.fineract.portfolio.loanaccount.guarantor.data.GuarantorFundingData;
 import org.apache.fineract.portfolio.loanaccount.guarantor.data.GuarantorTransactionData;
@@ -55,21 +53,20 @@ public class GuarantorReadPlatformServiceImpl implements GuarantorReadPlatformSe
     private final JdbcTemplate jdbcTemplate;
     private final ClientReadPlatformService clientReadPlatformService;
     private final StaffReadPlatformService staffReadPlatformService;
-    private final LoanRepository loanRepository;
+    private final LoanRepositoryWrapper loanRepositoryWrapper;
 
     @Autowired
     public GuarantorReadPlatformServiceImpl(final RoutingDataSource dataSource, final ClientReadPlatformService clientReadPlatformService,
-            final StaffReadPlatformService staffReadPlatformService, final LoanRepository loanRepository) {
+            final StaffReadPlatformService staffReadPlatformService, final LoanRepositoryWrapper loanRepositoryWrapper) {
         this.jdbcTemplate = new JdbcTemplate(dataSource);
         this.clientReadPlatformService = clientReadPlatformService;
         this.staffReadPlatformService = staffReadPlatformService;
-        this.loanRepository = loanRepository;
+        this.loanRepositoryWrapper = loanRepositoryWrapper;
     }
 
     @Override
     public List<GuarantorData> retrieveGuarantorsForValidLoan(final Long loanId) {
-        final Loan loan = this.loanRepository.findOne(loanId);
-        if (loan == null) { throw new LoanNotFoundException(loanId); }
+        this.loanRepositoryWrapper.findOneWithNotFoundDetection(loanId);
         return retrieveGuarantorsForLoan(loanId);
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/025ff9c7/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/service/GuarantorWritePlatformServiceJpaRepositoryIImpl.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/service/GuarantorWritePlatformServiceJpaRepositoryIImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/service/GuarantorWritePlatformServiceJpaRepositoryIImpl.java
index bea1f31..ab779af 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/service/GuarantorWritePlatformServiceJpaRepositoryIImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/guarantor/service/GuarantorWritePlatformServiceJpaRepositoryIImpl.java
@@ -97,7 +97,7 @@ public class GuarantorWritePlatformServiceJpaRepositoryIImpl implements Guaranto
     @Transactional
     public CommandProcessingResult createGuarantor(final Long loanId, final JsonCommand command) {
         final GuarantorCommand guarantorCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json());
-        final Loan loan = this.loanRepositoryWrapper.findOneWithNotFoundDetection(loanId);
+        final Loan loan = this.loanRepositoryWrapper.findOneWithNotFoundDetection(loanId, true);
         final List<Guarantor> existGuarantorList = this.guarantorRepository.findByLoan(loan);
         return createGuarantor(loan, command, guarantorCommand, existGuarantorList);
     }
@@ -186,7 +186,7 @@ public class GuarantorWritePlatformServiceJpaRepositoryIImpl implements Guaranto
             final GuarantorCommand guarantorCommand = this.fromApiJsonDeserializer.commandFromApiJson(command.json());
             guarantorCommand.validateForUpdate();
 
-            final Loan loan = this.loanRepositoryWrapper.findOneWithNotFoundDetection(loanId);
+            final Loan loan = this.loanRepositoryWrapper.findOneWithNotFoundDetection(loanId, true);
             validateLoanStatus(loan);
             final Guarantor guarantorForUpdate = this.guarantorRepository.findByLoanAndId(loan, guarantorId);
             if (guarantorForUpdate == null) { throw new GuarantorNotFoundException(loanId, guarantorId); }
@@ -239,7 +239,7 @@ public class GuarantorWritePlatformServiceJpaRepositoryIImpl implements Guaranto
     @Override
     @Transactional
     public CommandProcessingResult removeGuarantor(final Long loanId, final Long guarantorId, final Long guarantorFundingId) {
-        final Loan loan = this.loanRepositoryWrapper.findOneWithNotFoundDetection(loanId);
+        final Loan loan = this.loanRepositoryWrapper.findOneWithNotFoundDetection(loanId, true);
         validateLoanStatus(loan);
         final Guarantor guarantorForDelete = this.guarantorRepository.findByLoanAndId(loan, guarantorId);
         if (guarantorForDelete == null || (guarantorFundingId == null && !guarantorForDelete.getGuarantorFundDetails().isEmpty())) { throw new GuarantorNotFoundException(

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/025ff9c7/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractLoanScheduleGenerator.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractLoanScheduleGenerator.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractLoanScheduleGenerator.java
index 74350da..d249e35 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractLoanScheduleGenerator.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractLoanScheduleGenerator.java
@@ -2041,7 +2041,8 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
             final LocalDate scheduleTillDate) {
         // Loan transactions to process and find the variation on payments
         Collection<RecalculationDetail> recalculationDetails = new ArrayList<>();
-        for (LoanTransaction loanTransaction : loan.getLoanTransactions()) {
+        List<LoanTransaction> transactions = loan.getLoanTransactions() ;
+        for (LoanTransaction loanTransaction : transactions) {
             if (loanTransaction.isPaymentTransaction()) {
                 recalculationDetails.add(new RecalculationDetail(loanTransaction.getTransactionDate(), LoanTransaction
                         .copyTransactionProperties(loanTransaction)));

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/025ff9c7/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleAssembler.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleAssembler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleAssembler.java
index 9565ff3..a335e9c 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleAssembler.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleAssembler.java
@@ -598,14 +598,14 @@ public class LoanScheduleAssembler {
         validateDisbursementDateIsOnNonWorkingDay(loanApplicationTerms.getExpectedDisbursementDate(), workingDays);
         validateDisbursementDateIsOnHoliday(loanApplicationTerms.getExpectedDisbursementDate(), isHolidayEnabled, holidays);
 
-        Set<LoanDisbursementDetails> loanDisbursementDetails = this.loanUtilService.fetchDisbursementData(element.getAsJsonObject());
+        List<LoanDisbursementDetails> loanDisbursementDetails = this.loanUtilService.fetchDisbursementData(element.getAsJsonObject());
 
         return assembleLoanScheduleFrom(loanApplicationTerms, isHolidayEnabled, holidays, workingDays, element, loanDisbursementDetails);
     }
 
     public LoanScheduleModel assembleLoanScheduleFrom(final LoanApplicationTerms loanApplicationTerms, final boolean isHolidayEnabled,
             final List<Holiday> holidays, final WorkingDays workingDays, final JsonElement element,
-            Set<LoanDisbursementDetails> disbursementDetails) {
+            List<LoanDisbursementDetails> disbursementDetails) {
 
         final Set<LoanCharge> loanCharges = this.loanChargeAssembler.fromParsedJson(element, disbursementDetails);
 
@@ -657,7 +657,7 @@ public class LoanScheduleAssembler {
     public void assempleVariableScheduleFrom(final Loan loan, final String json) {
         this.variableLoanScheduleFromApiJsonValidator.validateSchedule(json, loan);
 
-        Set<LoanTermVariations> variations = loan.getLoanTermVariations();
+        List<LoanTermVariations> variations = loan.getLoanTermVariations();
         List<LoanTermVariations> newVariations = new ArrayList<>();
         extractLoanTermVariations(loan, json, newVariations);
 
@@ -839,7 +839,7 @@ public class LoanScheduleAssembler {
         loan.regenerateRepaymentSchedule(scheduleGeneratorDTO, currentUser);
     }
 
-    private List<LoanTermVariations> adjustExistingVariations(Set<LoanTermVariations> variations, List<LoanTermVariations> newVariations,
+    private List<LoanTermVariations> adjustExistingVariations(List<LoanTermVariations> variations, List<LoanTermVariations> newVariations,
             final Map<LocalDate, LocalDate> adjustDueDateVariations) {
         Map<LocalDate, LoanTermVariations> amountVariations = new HashMap<>();
         Map<LocalDate, LoanTermVariations> dueDateVariations = new HashMap<>();

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/025ff9c7/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformServiceImpl.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformServiceImpl.java
index a8ea977..2ebe0d4 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformServiceImpl.java
@@ -21,10 +21,8 @@ package org.apache.fineract.portfolio.loanaccount.loanschedule.service;
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Set;
 
 import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
 import org.apache.fineract.infrastructure.core.api.JsonQuery;
@@ -227,7 +225,7 @@ public class LoanScheduleCalculationPlatformServiceImpl implements LoanScheduleC
         final MonetaryCurrency currency = loan.getCurrency();
         Money outstanding = loan.getPrincpal();
 
-        Set<LoanDisbursementDetails> disbursementDetails = new HashSet<>();
+        List<LoanDisbursementDetails> disbursementDetails = new ArrayList<>();
         if (loan.isMultiDisburmentLoan()) {
             disbursementDetails = loan.getDisbursementDetails();
             outstanding = outstanding.zero();

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/025ff9c7/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleWritePlatformServiceImpl.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleWritePlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleWritePlatformServiceImpl.java
index 0999fe5..7191671 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleWritePlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleWritePlatformServiceImpl.java
@@ -22,7 +22,6 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 import org.apache.fineract.infrastructure.core.api.JsonCommand;
 import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
@@ -72,7 +71,7 @@ public class LoanScheduleWritePlatformServiceImpl implements LoanScheduleWritePl
         this.loanAccountDomainService.saveLoanWithDataIntegrityViolationChecks(loan);
         final Map<String, Object> changes = new HashMap<>();
         List<LoanTermVariationsData> newVariationsData = new ArrayList<>();
-        Set<LoanTermVariations> modifiedVariations = loan.getLoanTermVariations();
+        List<LoanTermVariations> modifiedVariations = loan.getLoanTermVariations();
         for (LoanTermVariations termVariations : modifiedVariations) {
             if (loanTermVariations.containsKey(termVariations.getId())) {
                 loanTermVariations.remove(termVariations.getId());
@@ -94,7 +93,7 @@ public class LoanScheduleWritePlatformServiceImpl implements LoanScheduleWritePl
     @Override
     public CommandProcessingResult deleteLoanScheduleVariations(final Long loanId) {
         final Loan loan = this.loanAssembler.assembleFrom(loanId);
-        Set<LoanTermVariations> variations = loan.getLoanTermVariations();
+        List<LoanTermVariations> variations = loan.getLoanTermVariations();
         List<Long> deletedVariations = new ArrayList<>(variations.size());
         for (LoanTermVariations loanTermVariations : variations) {
             deletedVariations.add(loanTermVariations.getId());

http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/025ff9c7/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/service/LoanRescheduleRequestReadPlatformServiceImpl.java
----------------------------------------------------------------------
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/service/LoanRescheduleRequestReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/service/LoanRescheduleRequestReadPlatformServiceImpl.java
index 19f6b79..632fe73 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/service/LoanRescheduleRequestReadPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/service/LoanRescheduleRequestReadPlatformServiceImpl.java
@@ -30,9 +30,7 @@ import org.apache.fineract.infrastructure.codes.service.CodeValueReadPlatformSer
 import org.apache.fineract.infrastructure.core.domain.JdbcSupport;
 import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
 import org.apache.fineract.portfolio.loanaccount.data.LoanTermVariationsData;
-import org.apache.fineract.portfolio.loanaccount.domain.Loan;
-import org.apache.fineract.portfolio.loanaccount.domain.LoanRepository;
-import org.apache.fineract.portfolio.loanaccount.exception.LoanNotFoundException;
+import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper;
 import org.apache.fineract.portfolio.loanaccount.rescheduleloan.data.LoanRescheduleRequestData;
 import org.apache.fineract.portfolio.loanaccount.rescheduleloan.data.LoanRescheduleRequestEnumerations;
 import org.apache.fineract.portfolio.loanaccount.rescheduleloan.data.LoanRescheduleRequestStatusEnumData;
@@ -49,15 +47,15 @@ import org.springframework.stereotype.Service;
 public class LoanRescheduleRequestReadPlatformServiceImpl implements LoanRescheduleRequestReadPlatformService {
 
     private final JdbcTemplate jdbcTemplate;
-    private final LoanRepository loanRepository;
+    private final LoanRepositoryWrapper loanRepositoryWrapper;
     private final LoanRescheduleRequestRowMapper loanRescheduleRequestRowMapper = new LoanRescheduleRequestRowMapper();
     private final CodeValueReadPlatformService codeValueReadPlatformService;
 
     @Autowired
-    public LoanRescheduleRequestReadPlatformServiceImpl(final RoutingDataSource dataSource, LoanRepository loanRepository,
+    public LoanRescheduleRequestReadPlatformServiceImpl(final RoutingDataSource dataSource, LoanRepositoryWrapper loanRepositoryWrapper,
             final CodeValueReadPlatformService codeValueReadPlatformService) {
         this.jdbcTemplate = new JdbcTemplate(dataSource);
-        this.loanRepository = loanRepository;
+        this.loanRepositoryWrapper = loanRepositoryWrapper;
         this.codeValueReadPlatformService = codeValueReadPlatformService;
     }
 
@@ -194,10 +192,7 @@ public class LoanRescheduleRequestReadPlatformServiceImpl implements LoanResched
     
     @Override
     public List<LoanRescheduleRequestData> readLoanRescheduleRequests(Long loanId) {
-        final Loan loan = this.loanRepository.findOne(loanId);
-
-        if (loan == null) { throw new LoanNotFoundException(loanId); }
-
+        this.loanRepositoryWrapper.findOneWithNotFoundDetection(loanId);
         final String sql = "select " + this.loanRescheduleRequestRowMapper.schema() + " where lr.loan_id = ?";
 
         return this.jdbcTemplate.query(sql, this.loanRescheduleRequestRowMapper, new Object[] { loanId });
@@ -219,12 +214,8 @@ public class LoanRescheduleRequestReadPlatformServiceImpl implements LoanResched
 
     @Override
     public List<LoanRescheduleRequestData> readLoanRescheduleRequests(Long loanId, Integer statusEnum) {
-        final Loan loan = this.loanRepository.findOne(loanId);
-
-        if (loan == null) { throw new LoanNotFoundException(loanId); }
-
+        this.loanRepositoryWrapper.findOneWithNotFoundDetection(loanId);
         final String sql = "select " + this.loanRescheduleRequestRowMapper.schema() + " where lr.loan_id = ?" + " and lr.status_enum = ?";
-
         return this.jdbcTemplate.query(sql, this.loanRescheduleRequestRowMapper, new Object[] { loanId, statusEnum });
     }