details: https://code.openbravo.com/erp/devel/pi/rev/b4dbd8ccb5ca changeset: 27556:b4dbd8ccb5ca user: Alvaro Ferraz <alvaro.ferraz <at> openbravo.com> date: Fri Sep 04 14:47:22 2015 +0200 summary: Fixes issue 30586: Performance problems in ProductCharacteristicEventHandler
Many loops inside ProductCharacteristicEventHandler have been replaced or removed. Loops to check if there is any wrong result, have been replaced with a unique result query. Loops inside getValuesToAdd method have been replaced with a query and results will be returned with a ScrollableResults. Loop to retrieve existingValues has been replaced with a query. diffstat: src/org/openbravo/event/ProductCharacteristicEventHandler.java | 198 ++++++--- 1 files changed, 125 insertions(+), 73 deletions(-) diffs (286 lines): diff -r fd369e6a0383 -r b4dbd8ccb5ca src/org/openbravo/event/ProductCharacteristicEventHandler.java --- a/src/org/openbravo/event/ProductCharacteristicEventHandler.java Wed Sep 09 13:35:01 2015 +0200 +++ b/src/org/openbravo/event/ProductCharacteristicEventHandler.java Fri Sep 04 14:47:22 2015 +0200 @@ -18,15 +18,12 @@ */ package org.openbravo.event; -import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; import javax.enterprise.event.Observes; -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; @@ -39,7 +36,6 @@ import org.openbravo.client.kernel.event.EntityNewEvent; import org.openbravo.client.kernel.event.EntityPersistenceEventObserver; import org.openbravo.client.kernel.event.EntityUpdateEvent; -import org.openbravo.dal.core.DalUtil; import org.openbravo.dal.service.OBCriteria; import org.openbravo.dal.service.OBDal; import org.openbravo.erpCommon.utility.OBMessageUtils; @@ -85,18 +81,28 @@ } if (prCh.isDefinesPrice()) { // Check there is only 1. - for (ProductCharacteristic prChAux : prCh.getProduct().getProductCharacteristicList()) { - if (prChAux.isDefinesPrice() && !prChAux.getId().equals(prCh.getId())) { - throw new OBException(OBMessageUtils.messageBD("DuplicateDefinesPrice")); - } + OBCriteria<ProductCharacteristic> criteria = OBDal.getInstance().createCriteria( + ProductCharacteristic.class); + criteria.add(Restrictions.eq(ProductCharacteristic.PROPERTY_PRODUCT, prCh.getProduct())); + criteria.add(Restrictions.eq(ProductCharacteristic.PROPERTY_DEFINESPRICE, true)); + criteria.add(Restrictions.ne(ProductCharacteristic.PROPERTY_ID, prCh.getId())); + criteria.setFilterOnActive(false); + criteria.setMaxResults(1); + if (criteria.uniqueResult() != null) { + throw new OBException(OBMessageUtils.messageBD("DuplicateDefinesPrice")); } } if (prCh.isDefinesImage()) { // Check there is only 1. - for (ProductCharacteristic prChAux : prCh.getProduct().getProductCharacteristicList()) { - if (prChAux.isDefinesImage() && !prChAux.getId().equals(prCh.getId())) { - throw new OBException(OBMessageUtils.messageBD("DuplicateDefinesImage")); - } + OBCriteria<ProductCharacteristic> criteria = OBDal.getInstance().createCriteria( + ProductCharacteristic.class); + criteria.add(Restrictions.eq(ProductCharacteristic.PROPERTY_PRODUCT, prCh.getProduct())); + criteria.add(Restrictions.eq(ProductCharacteristic.PROPERTY_DEFINESIMAGE, true)); + criteria.add(Restrictions.ne(ProductCharacteristic.PROPERTY_ID, prCh.getId())); + criteria.setFilterOnActive(false); + criteria.setMaxResults(1); + if (criteria.uniqueResult() != null) { + throw new OBException(OBMessageUtils.messageBD("DuplicateDefinesImage")); } } final Entity prodCharEntity = ModelProvider.getInstance().getEntity( @@ -107,10 +113,18 @@ @SuppressWarnings("unchecked") List<ProductCharacteristicConf> prChConfs = (List<ProductCharacteristicConf>) event .getCurrentState(charConfListProperty); - Set<String[]> newChValues = getValuesToAdd(prCh); - for (String[] strChValueId : newChValues) { - prChConfs - .add(getCharacteristicConf(prCh, strChValueId[0], strChValueId[1], strChValueId[2])); + + ScrollableResults scroll = getValuesToAdd(prCh); + try { + while (scroll.next()) { + Object[] strChValue = scroll.get(); + String chValueId = (String) strChValue[0]; + String chValueCode = (String) strChValue[1]; + Boolean chValueActive = (Boolean) strChValue[2]; + prChConfs.add(getCharacteristicConf(prCh, chValueId, chValueCode, chValueActive)); + } + } finally { + scroll.close(); } } } @@ -130,10 +144,16 @@ if (!event.getPreviousState(chProp).equals(event.getCurrentState(chProp))) { final Product prd = (Product) event.getCurrentState(prdProp); - for (ProductCharacteristicValue pChV : prd.getProductCharacteristicValueList()) { - if (pChV.getCharacteristic().equals(event.getPreviousState(chProp))) { - throw new OBException(OBMessageUtils.messageBD("UpdateProductChWithValue")); - } + // Check there is only 1. + OBCriteria<ProductCharacteristicValue> criteria = OBDal.getInstance().createCriteria( + ProductCharacteristicValue.class); + criteria.add(Restrictions.eq(ProductCharacteristicValue.PROPERTY_PRODUCT, prd)); + criteria.add(Restrictions.eq(ProductCharacteristicValue.PROPERTY_CHARACTERISTIC, + event.getPreviousState(chProp))); + criteria.setFilterOnActive(false); + criteria.setMaxResults(1); + if (criteria.uniqueResult() != null) { + throw new OBException(OBMessageUtils.messageBD("UpdateProductChWithValue")); } } @@ -151,18 +171,28 @@ } if (prCh.isDefinesPrice()) { // Check there is only 1. - for (ProductCharacteristic prChAux : prCh.getProduct().getProductCharacteristicList()) { - if (prChAux.isDefinesPrice() && !prChAux.getId().equals(prCh.getId())) { - throw new OBException(OBMessageUtils.messageBD("DuplicateDefinesPrice")); - } + OBCriteria<ProductCharacteristic> criteria = OBDal.getInstance().createCriteria( + ProductCharacteristic.class); + criteria.add(Restrictions.eq(ProductCharacteristic.PROPERTY_PRODUCT, prCh.getProduct())); + criteria.add(Restrictions.eq(ProductCharacteristic.PROPERTY_DEFINESPRICE, true)); + criteria.add(Restrictions.ne(ProductCharacteristic.PROPERTY_ID, prCh.getId())); + criteria.setFilterOnActive(false); + criteria.setMaxResults(1); + if (criteria.uniqueResult() != null) { + throw new OBException(OBMessageUtils.messageBD("DuplicateDefinesPrice")); } } if (prCh.isDefinesImage()) { // Check there is only 1. - for (ProductCharacteristic prChAux : prCh.getProduct().getProductCharacteristicList()) { - if (prChAux.isDefinesImage() && !prChAux.getId().equals(prCh.getId())) { - throw new OBException(OBMessageUtils.messageBD("DuplicateDefinesImage")); - } + OBCriteria<ProductCharacteristic> criteria = OBDal.getInstance().createCriteria( + ProductCharacteristic.class); + criteria.add(Restrictions.eq(ProductCharacteristic.PROPERTY_PRODUCT, prCh.getProduct())); + criteria.add(Restrictions.eq(ProductCharacteristic.PROPERTY_DEFINESIMAGE, true)); + criteria.add(Restrictions.ne(ProductCharacteristic.PROPERTY_ID, prCh.getId())); + criteria.setFilterOnActive(false); + criteria.setMaxResults(1); + if (criteria.uniqueResult() != null) { + throw new OBException(OBMessageUtils.messageBD("DuplicateDefinesImage")); } } @@ -172,29 +202,46 @@ List<ProductCharacteristicConf> prChConfs = (List<ProductCharacteristicConf>) event .getCurrentState(charConfListProperty); - final List<String> existingValues = new ArrayList<String>(); - for (ProductCharacteristicConf prChConf : prCh.getProductCharacteristicConfList()) { - existingValues.add((String) DalUtil.getId(prChConf.getCharacteristicValue())); + StringBuffer hql = new StringBuffer(); + hql.append(" select cv." + CharacteristicValue.PROPERTY_ID); + hql.append(" from " + ProductCharacteristicConf.ENTITY_NAME + " as pcc"); + hql.append(" join pcc." + ProductCharacteristicConf.PROPERTY_CHARACTERISTICVALUE + " as cv"); + hql.append(" where pcc." + ProductCharacteristicConf.PROPERTY_CHARACTERISTICOFPRODUCT + + " = :pc"); + Query query = OBDal.getInstance().getSession().createQuery(hql.toString()); + query.setParameter("pc", prCh); + @SuppressWarnings("unchecked") + final List<String> existingValues = query.list(); + + ScrollableResults scroll = getValuesToAdd(prCh); + try { + while (scroll.next()) { + Object[] strChValue = scroll.get(); + String chValueId = (String) strChValue[0]; + String chValueCode = (String) strChValue[1]; + Boolean chValueActive = (Boolean) strChValue[2]; + + if (existingValues.remove(chValueId)) { + OBCriteria<ProductCharacteristicConf> prChConfCrit = OBDal.getInstance() + .createCriteria(ProductCharacteristicConf.class); + prChConfCrit.add(Restrictions.eq( + ProductCharacteristicConf.PROPERTY_CHARACTERISTICOFPRODUCT, prCh)); + prChConfCrit.add(Restrictions.eq( + ProductCharacteristicConf.PROPERTY_CHARACTERISTICVALUE, + OBDal.getInstance().get(CharacteristicValue.class, chValueId))); + prChConfCrit.setFilterOnActive(false); + ProductCharacteristicConf prChConf = (ProductCharacteristicConf) prChConfCrit + .uniqueResult(); + prChConf.setCode(chValueCode); + prChConf.setActive(chValueActive); + continue; + } + prChConfs.add(getCharacteristicConf(prCh, chValueId, chValueCode, chValueActive)); + } + } finally { + scroll.close(); } - Set<String[]> valuesToAdd = getValuesToAdd(prCh); - for (String[] strNewValue : valuesToAdd) { - if (existingValues.remove(strNewValue[0])) { - OBCriteria<ProductCharacteristicConf> prChConfCrit = OBDal.getInstance().createCriteria( - ProductCharacteristicConf.class); - prChConfCrit.add(Restrictions.eq( - ProductCharacteristicConf.PROPERTY_CHARACTERISTICOFPRODUCT, prCh)); - prChConfCrit.add(Restrictions.eq(ProductCharacteristicConf.PROPERTY_CHARACTERISTICVALUE, - OBDal.getInstance().get(CharacteristicValue.class, strNewValue[0]))); - prChConfCrit.setFilterOnActive(false); - ProductCharacteristicConf prChConf = (ProductCharacteristicConf) prChConfCrit - .uniqueResult(); - prChConf.setCode(strNewValue[1]); - prChConf.setActive(Boolean.parseBoolean(strNewValue[2])); - OBDal.getInstance().save(prChConf); - continue; - } - prChConfs.add(getCharacteristicConf(prCh, strNewValue[0], strNewValue[1], strNewValue[2])); - } + // remove not needed if (!existingValues.isEmpty()) { for (String strChValueId : existingValues) { @@ -215,35 +262,40 @@ } } - private Set<String[]> getValuesToAdd(ProductCharacteristic prCh) { + private ScrollableResults getValuesToAdd(ProductCharacteristic prCh) { + // If a subset is defined insert only values of it. - Set<String[]> chValues = new HashSet<String[]>(); if (prCh.getCharacteristicSubset() != null) { - for (CharacteristicSubsetValue subsetValue : prCh.getCharacteristicSubset() - .getCharacteristicSubsetValueList()) { - String strCode = subsetValue.getCode(); - if (StringUtils.isBlank(strCode)) { - strCode = subsetValue.getCharacteristicValue().getCode(); - } - String[] strValues = { subsetValue.getCharacteristicValue().getId(), strCode, - subsetValue.getCharacteristicValue().isActive().toString() }; - chValues.add(strValues); - } - return chValues; + StringBuffer hql = new StringBuffer(); + hql.append(" select cv." + CharacteristicValue.PROPERTY_ID); + hql.append(" , coalesce(csv." + CharacteristicSubsetValue.PROPERTY_CODE + ", cv." + + CharacteristicValue.PROPERTY_CODE + ")"); + hql.append(" , cv." + CharacteristicValue.PROPERTY_ACTIVE); + hql.append(" from " + CharacteristicSubsetValue.ENTITY_NAME + " as csv"); + hql.append(" join csv." + CharacteristicSubsetValue.PROPERTY_CHARACTERISTICVALUE + " as cv"); + hql.append(" where csv." + CharacteristicSubsetValue.PROPERTY_CHARACTERISTICSUBSET + " = :cs"); + Query query = OBDal.getInstance().getSession().createQuery(hql.toString()); + query.setParameter("cs", prCh.getCharacteristicSubset()); + return query.scroll(ScrollMode.FORWARD_ONLY); } + // Add all not summary values. - for (CharacteristicValue chValue : prCh.getCharacteristic().getCharacteristicValueList()) { - if (!chValue.isSummaryLevel()) { - String[] strValues = { chValue.getId(), chValue.getCode(), - chValue.get(CharacteristicValue.PROPERTY_ACTIVE).toString() }; - chValues.add(strValues); - } + else { + StringBuffer hql = new StringBuffer(); + hql.append(" select cv." + CharacteristicValue.PROPERTY_ID); + hql.append(" , cv." + CharacteristicValue.PROPERTY_CODE); + hql.append(" , cv." + CharacteristicValue.PROPERTY_ACTIVE); + hql.append(" from " + CharacteristicValue.ENTITY_NAME + " as cv"); + hql.append(" where cv." + CharacteristicValue.PROPERTY_CHARACTERISTIC + " = :c"); + hql.append(" and cv." + CharacteristicValue.PROPERTY_SUMMARYLEVEL + " = false"); + Query query = OBDal.getInstance().getSession().createQuery(hql.toString()); + query.setParameter("c", prCh.getCharacteristic()); + return query.scroll(ScrollMode.FORWARD_ONLY); } - return chValues; } private ProductCharacteristicConf getCharacteristicConf(ProductCharacteristic prCh, - String strCharacteristicValueId, String strCode, String strActive) { + String strCharacteristicValueId, String strCode, Boolean strActive) { ProductCharacteristicConf charConf = OBProvider.getInstance().get( ProductCharacteristicConf.class); charConf.setCharacteristicOfProduct(prCh); @@ -251,7 +303,7 @@ charConf.setCharacteristicValue((CharacteristicValue) OBDal.getInstance().getProxy( CharacteristicValue.ENTITY_NAME, strCharacteristicValueId)); charConf.setCode(strCode); - charConf.setActive(Boolean.parseBoolean(strActive)); + charConf.setActive(strActive); return charConf; } ------------------------------------------------------------------------------ Monitor Your Dynamic Infrastructure at Any Scale With Datadog! Get real-time metrics from all of your servers, apps and tools in one place. SourceForge users - Click here to start your Free Trial of Datadog now! http://pubads.g.doubleclick.net/gampad/clk?id=241902991&iu=/4140 _______________________________________________ Openbravo-commits mailing list Openbravo-commits@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openbravo-commits