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 1a3428317608615959089000093e58951daa155d..43caf1f12bd68ad8dc93e49f398de36c683b32ec 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 @@ -21,7 +21,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.Deque; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; @@ -147,9 +146,10 @@ final class DataDAO extends AbstractGenericEntityWithPropertiesDAO<DataPE> imple @Override public Object doInHibernate(Session session) throws HibernateException { - SQLQuery query = session.createSQLQuery("select distinct samp_id from data where samp_id in (:sampleIds)"); - query.setParameterList("sampleIds", sampleIds); - List<Number> list = query.list(); + + InQuery inQuery = new InQuery<Long, Number>(); + List<Number> list = + inQuery.withBatch(session, "select distinct samp_id from data where samp_id in (:sampleIds)", "sampleIds", sampleIds); Set<Long> ids = new HashSet<Long>(); for (Number item : list) { @@ -1330,11 +1330,11 @@ final class DataDAO extends AbstractGenericEntityWithPropertiesDAO<DataPE> imple flushWithSqlExceptionHandling(getHibernateTemplate()); scheduleDynamicPropertiesEvaluation(dataSets); - + // if session is not cleared registration of many samples slows down after each batch hibernateTemplate.clear(); } - + @Override public final void validateAndSaveUpdatedEntity(DataPE entity) throws DataAccessException { @@ -1344,13 +1344,13 @@ final class DataDAO extends AbstractGenericEntityWithPropertiesDAO<DataPE> imple } @Override - protected void scheduleDynamicPropertiesEvaluation(List<DataPE> dataSets) + protected void scheduleDynamicPropertiesEvaluation(List<DataPE> dataSets) { List<DataPE> toUpdate = new ArrayList<DataPE>(); addAllDataSetsAndComponentsRecursively(toUpdate, dataSets); super.scheduleDynamicPropertiesEvaluation(toUpdate); } - + private void addAllDataSetsAndComponentsRecursively(List<DataPE> resultDataSets, List<DataPE> dataSets) { for (DataPE dataSet : dataSets) @@ -1359,7 +1359,7 @@ final class DataDAO extends AbstractGenericEntityWithPropertiesDAO<DataPE> imple addAllDataSetsAndComponentsRecursively(resultDataSets, dataSet.getContainedDataSets()); } } - + @Override public List<TechId> listDataSetIdsBySampleIds(final Collection<TechId> samples) { diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/InQuery.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/InQuery.java new file mode 100644 index 0000000000000000000000000000000000000000..0c587b01bbe0b425a42273fb1faf33408a5f5a54 --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/InQuery.java @@ -0,0 +1,37 @@ +package ch.systemsx.cisd.openbis.generic.server.dataaccess.db; + +import java.util.ArrayList; +import java.util.List; + +import org.hibernate.SQLQuery; +import org.hibernate.Session; + +public class InQuery<I, O> +{ + private static final int POSTGRES_DRIVER_MAX_ARGS = 32767; // Uses a signed 2 bytes integer + + public List<O> withBatch(Session session, String inQuery, String inParameter, List<I> inArguments) + { + List<O> result = new ArrayList<O>(inArguments.size()); + + int fromIndex = 0; + while (fromIndex < inArguments.size()) + { + int toIndex = fromIndex + POSTGRES_DRIVER_MAX_ARGS; + if (toIndex > inArguments.size()) + { + toIndex = inArguments.size(); + } + + List<I> partialInArguments = inArguments.subList(fromIndex, toIndex); + + SQLQuery query = session.createSQLQuery(inQuery); + query.setParameterList(inParameter, partialInArguments); + List<O> partialResult = query.list(); + result.addAll(partialResult); + fromIndex = toIndex; + } + + return result; + } +} \ No newline at end of file diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/UpdateSampleTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/UpdateSampleTest.java index 2472b3328530f1e1bc3a2f1451b36a3f719d1d4a..80aac39c4ba4d04187a7ac2362f25da9f3ee38dd 100644 --- a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/UpdateSampleTest.java +++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/asapi/v3/UpdateSampleTest.java @@ -52,7 +52,6 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.tag.id.TagCode; import ch.ethz.sis.openbis.systemtest.asapi.v3.index.ReindexingState; import ch.systemsx.cisd.common.action.IDelegatedAction; import ch.systemsx.cisd.common.test.AssertionUtil; - import junit.framework.Assert; /** @@ -61,6 +60,25 @@ import junit.framework.Assert; public class UpdateSampleTest extends AbstractSampleTest { + @Test + public void testUpdateBiggerThanPostgresDriverArgumentsLimitWithIndexCheck() + { + String sessionToken = v3api.login(TEST_USER, PASSWORD); + ReindexingState state = new ReindexingState(); + List<SampleUpdate> updates = new ArrayList<SampleUpdate>(); + for (int i = 0; i < 40000; i++) + { + SampleUpdate update = new SampleUpdate(); + update.setSampleId(new SamplePermId("200811050945092-976")); + update.setProperty("OFFSET", "50"); + updates.add(update); + } + + v3api.updateSamples(sessionToken, updates); + + assertSamplesReindexed(state, "200811050945092-976"); + } + @Test public void testUpdateWithIndexCheck() {