details:   https://code.openbravo.com/erp/devel/pi/rev/694b153db283
changeset: 26105:694b153db283
user:      Alvaro Ferraz <alvaro.ferraz <at> openbravo.com>
date:      Fri Feb 20 09:46:32 2015 +0100
summary:   Fixes issue 28817: OutOfMemory importing bank statement using the 
csv importer

ScrollableResults object, used to scrolls OBQuery of business partners when 
importing bank statements, was directly closed to release resources, between 
each line's iteration of the csv file. This change avoids the memory overusing, 
so now it is possible to import a csv file with 4000 lines or more. Also, 
OBCriteria has been changed into Query in order to use arryas instead of DAL 
objects what reduces the memory usage.

diffstat:

 
modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/utility/FIN_BankStatementImport.java
 |  139 ++++++---
 1 files changed, 91 insertions(+), 48 deletions(-)

diffs (197 lines):

diff -r f1360ce4b3d1 -r 694b153db283 
modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/utility/FIN_BankStatementImport.java
--- 
a/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/utility/FIN_BankStatementImport.java
        Mon Mar 02 13:45:56 2015 +0100
+++ 
b/modules/org.openbravo.advpaymentmngt/src/org/openbravo/advpaymentmngt/utility/FIN_BankStatementImport.java
        Fri Feb 20 09:46:32 2015 +0100
@@ -11,7 +11,7 @@
  * under the License.
  * The Original Code is Openbravo ERP.
  * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2010-2013 Openbravo SLU
+ * All portions are Copyright (C) 2010-2015 Openbravo SLU
  * All Rights Reserved.
  * Contributor(s):  ______________________________________.
  *************************************************************************
@@ -31,6 +31,7 @@
 import org.apache.commons.fileupload.FileItem;
 import org.apache.commons.lang.StringUtils;
 import org.apache.log4j.Logger;
+import org.hibernate.Query;
 import org.hibernate.ScrollMode;
 import org.hibernate.ScrollableResults;
 import org.hibernate.criterion.Restrictions;
@@ -257,6 +258,7 @@
       } else {
         OBDal.getInstance().remove(bankStatementLine);
       }
+
     }
     OBDal.getInstance().flush();
     return counter;
@@ -360,6 +362,7 @@
       final OBQuery<BusinessPartner> bp = 
OBDal.getInstance().createQuery(BusinessPartner.class,
           whereClause.toString(), parameters);
       bp.setFilterOnReadableOrganization(false);
+      bp.setMaxResult(1);
       List<BusinessPartner> matchedBP = bp.list();
       if (matchedBP.size() == 0)
         return null;
@@ -396,73 +399,113 @@
       return null;
     }
     final StringBuilder whereClause = new StringBuilder();
-    List<Object> parameters = new ArrayList<Object>();
     OBContext.setAdminMode();
+    ScrollableResults businessPartnersScroll = null;
     try {
-      whereClause.append(" as b ");
+      whereClause.append("select b.id as id, b.name as name from ");
+      whereClause.append(" BusinessPartner b ");
       whereClause.append(" where (");
       for (String token : list) {
-        whereClause.append(" lower(b." + BusinessPartner.PROPERTY_NAME + ") 
like lower(?) or ");
-        parameters.add("%" + token + "%");
+        whereClause.append(" lower(b." + BusinessPartner.PROPERTY_NAME + ") 
like lower('%" + token
+            + "%') or ");
       }
       whereClause.delete(whereClause.length() - 3, 
whereClause.length()).append(")");
       whereClause.append(" and b." + BusinessPartner.PROPERTY_ORGANIZATION + 
".id in (");
       whereClause.append(Utility.getInStrSet(new 
OrganizationStructureProvider()
           .getNaturalTree(organization.getId())) + ") ");
-      final OBQuery<BusinessPartner> bl = 
OBDal.getInstance().createQuery(BusinessPartner.class,
-          whereClause.toString(), parameters);
-      bl.setFilterOnReadableOrganization(false);
+      final Query bl = 
OBDal.getInstance().getSession().createQuery(whereClause.toString());
+      businessPartnersScroll = bl.scroll(ScrollMode.SCROLL_SENSITIVE);
 
-      final ScrollableResults businessPartnersScroll = 
bl.scroll(ScrollMode.SCROLL_SENSITIVE);
-      int countBp = bl.count();
-      if (countBp == 0) {
+      if (!businessPartnersScroll.next()) {
         return null;
-      } else if (countBp == 1) {
-        businessPartnersScroll.next();
-        return (BusinessPartner) businessPartnersScroll.get(0);
-      } else {
-        BusinessPartner closest = closest(businessPartnersScroll, partnername);
+      }
 
-        return closest;
+      else {
+        final Object[] resultObject = (Object[]) businessPartnersScroll.get(0);
+        if (!businessPartnersScroll.next()) {
+          String strParnterId = "";
+          if (resultObject.getClass().isArray()) {
+            final Object[] values = (Object[]) resultObject;
+            strParnterId = (String) values[0];
+          }
+          BusinessPartner bp = OBDal.getInstance().get(BusinessPartner.class, 
strParnterId);
+          return bp;
+        }
+
+        else {
+          String closestId = closest(businessPartnersScroll, partnername);
+          BusinessPartner closest = 
OBDal.getInstance().get(BusinessPartner.class, closestId);
+          return closest;
+        }
       }
 
     } finally {
+      businessPartnersScroll.close();
       OBContext.restorePreviousMode();
     }
   }
 
-  private BusinessPartner closest(ScrollableResults businessPartners, String 
partnername) {
-    businessPartners.next();
-    BusinessPartner targetBusinessPartner = (BusinessPartner) 
businessPartners.get(0);
-    businessPartners.beforeFirst();
-    int distance = StringUtils.getLevenshteinDistance(partnername, 
targetBusinessPartner.getName());
-    String parsedPartnername = partnername.toLowerCase();
-    // Remove exceptions
-    for (String eliminate : stringExceptions) {
-      parsedPartnername = 
parsedPartnername.replaceAll(eliminate.toLowerCase(), "");
+  private String closest(ScrollableResults businessPartners, String 
partnername) {
+    String targetBusinessPartnerId = "";
+    try {
+      businessPartners.beforeFirst();
+      businessPartners.next();
+      Object[] resultObject = (Object[]) businessPartners.get(0);
+
+      String targetBusinessPartnerName = "";
+      if (resultObject.getClass().isArray()) {
+        final Object[] values = (Object[]) resultObject;
+        targetBusinessPartnerId = (String) values[0];
+        targetBusinessPartnerName = (String) values[1];
+      }
+
+      int distance = StringUtils.getLevenshteinDistance(partnername, 
targetBusinessPartnerName);
+      String parsedPartnername = partnername.toLowerCase();
+      // Remove exceptions
+      for (String eliminate : stringExceptions) {
+        parsedPartnername = 
parsedPartnername.replaceAll(eliminate.toLowerCase(), "");
+      }
+
+      // Remove Numeric characters
+      char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
+      for (char character : digits) {
+        parsedPartnername = parsedPartnername.replace(character, ' ');
+        parsedPartnername = parsedPartnername.trim();
+      }
+
+      businessPartners.beforeFirst();
+      int i = 0;
+      while (businessPartners.next()) {
+        i++;
+        String bpId = "";
+        String bpName = "";
+        resultObject = (Object[]) businessPartners.get(0);
+        if (resultObject.getClass().isArray()) {
+          final Object[] values = (Object[]) resultObject;
+          bpId = (String) values[0];
+          bpName = (String) values[1];
+        }
+        // Calculates distance between two strings meaning number of changes 
required for a string
+        // to
+        // convert in another string
+        int bpDistance = StringUtils
+            .getLevenshteinDistance(parsedPartnername, bpName.toLowerCase());
+        if (bpDistance < distance) {
+          distance = bpDistance;
+          targetBusinessPartnerId = bpId;
+        }
+        if (i % 100 == 0) {
+          OBDal.getInstance().flush();
+          OBDal.getInstance().getSession().clear();
+        }
+      }
+      return targetBusinessPartnerId;
+    } catch (Exception e) {
+      log4j.error(e.getStackTrace());
+    } finally {
+      return targetBusinessPartnerId;
     }
-    // Remove Numeric characters
-    char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
-    for (char character : digits) {
-      parsedPartnername = parsedPartnername.replace(character, ' ');
-      parsedPartnername = parsedPartnername.trim();
-    }
-    while (businessPartners.next()) {
-      BusinessPartner bp = (BusinessPartner) businessPartners.get(0);
-      // Calculates distance between two strings meaning number of changes 
required for a string to
-      // convert in another string
-      int bpDistance = StringUtils.getLevenshteinDistance(parsedPartnername, 
bp.getName()
-          .toLowerCase());
-      if (bpDistance < distance) {
-        distance = bpDistance;
-        OBDal.getInstance().getSession().evict(targetBusinessPartner);
-        targetBusinessPartner = bp;
-      } else {
-        OBDal.getInstance().getSession().evict(bp);
-      }
-      // The clear is not done because the evict is being done previously
-    }
-    return targetBusinessPartner;
+
   }
 
   private BankFileFormat getBankFileFormat() {

------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
Openbravo-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openbravo-commits

Reply via email to