From b2ee03558430fe21f4ef03c1dcf4de66f79415d5 Mon Sep 17 00:00:00 2001
From: juanf <juanf>
Date: Thu, 6 Oct 2016 08:07:57 +0000
Subject: [PATCH] SSDM-4192 : Bugfix, Batch InQuery class to avoid postgres
 driver limit with test.

SVN: 37145
---
 .../generic/server/dataaccess/db/DataDAO.java | 18 ++++-----
 .../generic/server/dataaccess/db/InQuery.java | 37 +++++++++++++++++++
 .../systemtest/asapi/v3/UpdateSampleTest.java | 20 +++++++++-
 3 files changed, 65 insertions(+), 10 deletions(-)
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/InQuery.java

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 1a342831760..43caf1f12bd 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 00000000000..0c587b01bbe
--- /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 2472b332853..80aac39c4ba 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()
     {
-- 
GitLab