From 3ad93d23fbbab41b5b54960d6a45fa8653bfad91 Mon Sep 17 00:00:00 2001
From: juanf <juanf>
Date: Wed, 8 Mar 2017 13:34:42 +0000
Subject: [PATCH] SSDM-4682 : bugix, openBIS empty trashcan breaks when num
 entities over 2-byte due to SQL IN

SVN: 37867
---
 .../generic/server/dataaccess/db/InQuery.java | 17 ++------
 .../server/dataaccess/db/InQueryScroller.java | 40 +++++++++++++++++++
 .../server/dataaccess/db/SampleDAO.java       | 24 ++++++++---
 3 files changed, 63 insertions(+), 18 deletions(-)
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/InQueryScroller.java

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
index 8585869bba1..69538d9ab55 100644
--- 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
@@ -9,24 +9,16 @@ 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, Map<String, Object> fixParams)
     {
         List<O> result = new ArrayList<O>(inArguments.size());
-
         int fixParamsSize = (fixParams == null) ? 0 : fixParams.size();
-        int fromIndex = 0;
 
-        while (fromIndex < inArguments.size())
-        {
-            int toIndex = fromIndex + POSTGRES_DRIVER_MAX_ARGS - fixParamsSize;
-            if (toIndex > inArguments.size())
-            {
-                toIndex = inArguments.size();
-            }
+        InQueryScroller<I> scroller = new InQueryScroller<>(inArguments, fixParamsSize);
+        List<I> partialInArguments = null;
 
-            List<I> partialInArguments = inArguments.subList(fromIndex, toIndex);
+        while ((partialInArguments = scroller.next()) != null)
+        {
             SQLQuery query = session.createSQLQuery(inQuery);
             query.setParameterList(inParameter, partialInArguments);
 
@@ -39,7 +31,6 @@ public class InQuery<I, O>
             }
             List<O> partialResult = query.list();
             result.addAll(partialResult);
-            fromIndex = toIndex;
         }
 
         return result;
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/InQueryScroller.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/InQueryScroller.java
new file mode 100644
index 00000000000..49cbd0204c7
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/InQueryScroller.java
@@ -0,0 +1,40 @@
+package ch.systemsx.cisd.openbis.generic.server.dataaccess.db;
+
+import java.util.List;
+
+public class InQueryScroller<I>
+{
+    private static final int POSTGRES_DRIVER_MAX_ARGS = 32767; // Uses a signed 2 bytes integer
+
+    private List<I> inArguments;
+
+    private int fromIndex;
+
+    private int fixParamsSize;
+
+    public InQueryScroller(List<I> inArguments, int fixParamsSize)
+    {
+        this.inArguments = inArguments;
+        this.fromIndex = 0;
+        this.fixParamsSize = fixParamsSize;
+    }
+
+    public List<I> next()
+    {
+        if (fromIndex < inArguments.size())
+        {
+            int toIndex = fromIndex + POSTGRES_DRIVER_MAX_ARGS - fixParamsSize;
+            if (toIndex > inArguments.size())
+            {
+                toIndex = inArguments.size();
+            }
+
+            List<I> partialInArguments = inArguments.subList(fromIndex, toIndex);
+            fromIndex = toIndex;
+            return partialInArguments;
+        } else
+        {
+            return null;
+        }
+    }
+}
\ No newline at end of file
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/SampleDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/SampleDAO.java
index a4f88a026bf..099a1568b8e 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/SampleDAO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/dataaccess/db/SampleDAO.java
@@ -247,7 +247,7 @@ public class SampleDAO extends AbstractGenericEntityWithPropertiesDAO<SamplePE>
     {
         assert sampleCode != null : "Unspecified sample code.";
         assert project != null : "Unspecified project.";
-        
+
         Criteria criteria = createProjectCriteria(project);
         addSampleCodeCriterion(criteria, sampleCode);
         SamplePE sample = (SamplePE) criteria.uniqueResult();
@@ -352,7 +352,7 @@ public class SampleDAO extends AbstractGenericEntityWithPropertiesDAO<SamplePE>
     {
         return createFindCriteria(Restrictions.eq("project", project));
     }
-    
+
     private void addSampleCodesCriterion(Criteria criteria, List<String> sampleCodes,
             String containerCodeOrNull)
     {
@@ -609,9 +609,23 @@ public class SampleDAO extends AbstractGenericEntityWithPropertiesDAO<SamplePE>
                     }
 
                     String permIds = permIdList.substring(2);
-                    String content = historyCreator.apply(session, entityIdsToDelete, createQueryPropertyHistorySQL(),
-                            createQueryRelationshipHistorySQL(), createQueryAttributesSQL(), null,
-                            AttachmentHolderKind.SAMPLE, registrator);
+
+                    InQueryScroller<Long> entityIdsToDeleteScroller = new InQueryScroller<>(entityIdsToDelete, 16384 /*
+                                                                                                                      * createQueryPropertyHistorySQL
+                                                                                                                      * uses the parameters twice
+                                                                                                                      */);
+                    List<Long> partialEntityIdsToDelete = null;
+                    String content = "";
+                    while ((partialEntityIdsToDelete = entityIdsToDeleteScroller.next()) != null)
+                    {
+                        if (content.length() > 0)
+                        {
+                            content += ", ";
+                        }
+                        content += historyCreator.apply(session, partialEntityIdsToDelete, createQueryPropertyHistorySQL(),
+                                createQueryRelationshipHistorySQL(), createQueryAttributesSQL(), null,
+                                AttachmentHolderKind.SAMPLE, registrator);
+                    }
 
                     SQLQuery deleteProperties = session.createSQLQuery(properties);
                     deleteProperties.setParameter("id", deletion.getId());
-- 
GitLab