From 0e2069753c53fbd37ce7fc88ae44d8cb958076b7 Mon Sep 17 00:00:00 2001 From: gpawel <gpawel> Date: Tue, 14 Feb 2012 13:46:05 +0000 Subject: [PATCH] fixing bad performance of listRelatedDataSets SVN: 24453 --- .../openbis/generic/server/CommonServer.java | 23 +++++++- .../generic/server/dataaccess/IDataDAO.java | 8 ++- .../generic/server/dataaccess/db/DataDAO.java | 57 +++++++++++++++---- 3 files changed, 72 insertions(+), 16 deletions(-) diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java index d3063464789..39965fa5e99 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java @@ -22,10 +22,12 @@ import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Date; +import java.util.EnumMap; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import org.springframework.dao.DataAccessException; @@ -1025,11 +1027,30 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt final List<? extends IEntityInformationHolder> relatedEntities) { final IDataDAO dataDAO = getDAOFactory().getDataDAO(); + EnumMap<EntityKind, List<IEntityInformationHolder>> entities = + new EnumMap<EntityKind, List<IEntityInformationHolder>>(EntityKind.class); + for (IEntityInformationHolder entity : relatedEntities) { if (isEntityKindRelatedWithDataSets(entity.getEntityKind())) { - List<DataPE> relatedDataSets = dataDAO.listRelatedDataSets(entity); + List<IEntityInformationHolder> entitiesOfGivenKind = + entities.get(entity.getEntityKind()); + if (entitiesOfGivenKind == null) + { + entitiesOfGivenKind = new ArrayList<IEntityInformationHolder>(); + entities.put(entity.getEntityKind(), entitiesOfGivenKind); + } + entitiesOfGivenKind.add(entity); + } + } + + for (Entry<EntityKind, List<IEntityInformationHolder>> entry : entities.entrySet()) + { + if (entry.getValue() != null && entry.getValue().size() > 0) + { + List<DataPE> relatedDataSets = + dataDAO.listRelatedDataSets(entry.getValue(), entry.getKey()); resultSet.addAll(relatedDataSets); } } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IDataDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IDataDAO.java index 40bfe33d6a3..7189bd2c786 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IDataDAO.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/IDataDAO.java @@ -25,6 +25,7 @@ import org.springframework.dao.DataAccessException; import ch.systemsx.cisd.openbis.generic.shared.basic.IEntityInformationHolder; import ch.systemsx.cisd.openbis.generic.shared.basic.TechId; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetArchivingStatus; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind; import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE; import ch.systemsx.cisd.openbis.generic.shared.dto.DataStorePE; import ch.systemsx.cisd.openbis.generic.shared.dto.DeletedDataPE; @@ -46,12 +47,13 @@ public interface IDataDAO extends IGenericDAO<DataPE> public boolean hasDataSet(final SamplePE sample) throws DataAccessException; /** - * List the {@link DataPE} related to given <var>entity</var>. + * List the {@link DataPE} related to given <var>entities</var> of specified + * <var>entityKind</var>. * * @returns list of {@link DataPE}s that are related to given {@link IEntityInformationHolder}. */ - public List<DataPE> listRelatedDataSets(final IEntityInformationHolder entity) - throws DataAccessException; + public List<DataPE> listRelatedDataSets(final List<IEntityInformationHolder> entities, + EntityKind entityKind) throws DataAccessException; /** * List the {@link DataPE} for given <var>sample</var>. diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DataDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DataDAO.java index 9c3480a9757..71dc6e82732 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DataDAO.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/DataDAO.java @@ -56,6 +56,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.CodeConverter; import ch.systemsx.cisd.openbis.generic.shared.basic.IEntityInformationHolder; import ch.systemsx.cisd.openbis.generic.shared.basic.TechId; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetArchivingStatus; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind; import ch.systemsx.cisd.openbis.generic.shared.dto.ColumnNames; import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE; import ch.systemsx.cisd.openbis.generic.shared.dto.DataStorePE; @@ -110,28 +111,60 @@ final class DataDAO extends AbstractGenericEntityWithPropertiesDAO<DataPE> imple return count > 0; } - public final List<DataPE> listRelatedDataSets(final IEntityInformationHolder entity) - throws DataAccessException + public final List<DataPE> listRelatedDataSets(final List<IEntityInformationHolder> entities, + EntityKind entityKind) throws DataAccessException { - assert entity != null : "Unspecified entity."; + assert entities != null : "Unspecified entities."; + assert entities.size() > 0 : "Empty entities."; + assert entityKind != null : "Unspecified entity kind."; - final String entityName = entity.getEntityKind().toString().toLowerCase(); + final String entityName = entityKind.toString().toLowerCase(); final String query = String.format("from %s e " + "left join fetch e.experimentInternal " + "left join fetch e.sampleInternal " + "left join fetch e.parents " + "left join fetch e.containedDataSets " - + "left join fetch e.dataSetProperties " + "where e.%sInternal.id = ?", - TABLE_NAME, entityName); - final List<DataPE> list = cast(getHibernateTemplate().find(query, toArray(entity.getId()))); + + "left join fetch e.dataSetProperties " + + "where e.%sInternal.id IN (:ids)", TABLE_NAME, entityName); - // distinct does not work properly in HQL for left joins - distinct(list); + final List<Long> ids = new ArrayList<Long>(); + for (IEntityInformationHolder entity : entities) + { + ids.add(entity.getId()); + } + final List<DataPE> results = new ArrayList<DataPE>(); + BatchOperationExecutor.executeInBatches(new IBatchOperation<Long>() + { + public void execute(List<Long> entityIds) + { + + final List<DataPE> list = + cast(getHibernateTemplate().findByNamedParam(query, "ids", entityIds)); + results.addAll(list); + } + + public List<Long> getAllEntities() + { + return ids; + } + + public String getEntityName() + { + return "dataSet"; + } + + public String getOperationName() + { + return "listRelatedDataSets"; + } + }); + + distinct(results); if (operationLog.isDebugEnabled()) { - operationLog.debug(String.format("%d external data have been found for [entity=%s].", - list.size(), entity)); + operationLog.debug(String.format("%d external data have been found for %d entities.", + results.size(), entities.size())); } - return list; + return results; } public final List<DataPE> listDataSets(final SamplePE sample) throws DataAccessException -- GitLab