diff --git a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/HCSDatasetUploader.java b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/HCSDatasetUploader.java
index 5178e36ea11c8490a438e974cb976b08de80c9ef..a183843d177fd74cff9c3cd49e9970968b6a349e 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/HCSDatasetUploader.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/dss/etl/HCSDatasetUploader.java
@@ -116,7 +116,7 @@ public class HCSDatasetUploader
                 new HashMap<ImgChannelStackDTO, List<AcquiredImageInStack>>();
         for (AcquiredPlateImage image : images)
         {
-            ImgChannelStackDTO stackDTO = makeStackDTO(image, spotIds, datasetId);
+            ImgChannelStackDTO stackDTO = makeStackDtoWithouId(image, spotIds, datasetId);
             List<AcquiredImageInStack> stackImages = map.get(stackDTO);
             if (stackImages == null)
             {
@@ -125,21 +125,31 @@ public class HCSDatasetUploader
             stackImages.add(makeAcquiredImageInStack(image));
             map.put(stackDTO, stackImages);
         }
+        setChannelStackIds(map.keySet());
         return map;
     }
 
+    private void setChannelStackIds(Set<ImgChannelStackDTO> channelStacks)
+    {
+        for (ImgChannelStackDTO channelStack : channelStacks)
+        {
+            channelStack.setId(dao.createChannelStackId());
+        }
+    }
+
     private static AcquiredImageInStack makeAcquiredImageInStack(AcquiredPlateImage image)
     {
         return new AcquiredImageInStack(image.getChannelName(), image.getImageReference(), image
                 .getThumbnailFilePathOrNull());
     }
 
-    private ImgChannelStackDTO makeStackDTO(AcquiredPlateImage image, Long[][] spotIds,
+    private ImgChannelStackDTO makeStackDtoWithouId(AcquiredPlateImage image, Long[][] spotIds,
             long datasetId)
     {
         long spotId = getSpotId(image, spotIds);
-        return new ImgChannelStackDTO(dao.createChannelStackId(), image.getTileRow(), image
-                .getTileColumn(), datasetId, spotId, image.tryGetTimePoint(), image.tryGetDepth());
+        int dummyId = 0;
+        return new ImgChannelStackDTO(dummyId, image.getTileRow(), image.getTileColumn(),
+                datasetId, spotId, image.tryGetTimePoint(), image.tryGetDepth());
     }
 
     private static long getSpotId(AcquiredPlateImage image, Long[][] spotIds)
diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/ImgChannelStackDTO.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/ImgChannelStackDTO.java
index e8d9f77f446e55878c537803a713730b7ffd1fee..7f7fbf71229b8fc8e90d8434630590d9ad11840f 100644
--- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/ImgChannelStackDTO.java
+++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/ImgChannelStackDTO.java
@@ -18,12 +18,14 @@ package ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess;
 
 import net.lemnik.eodsql.ResultColumn;
 
-import ch.systemsx.cisd.common.utilities.AbstractHashable;
+import org.apache.commons.lang.builder.ToStringBuilder;
+
+import ch.systemsx.cisd.common.utilities.ModifiedShortPrefixToStringStyle;
 
 /**
  * @author Tomasz Pylak
  */
-public class ImgChannelStackDTO extends AbstractHashable
+public class ImgChannelStackDTO
 {
     @ResultColumn("ID")
     private long id;
@@ -129,4 +131,68 @@ public class ImgChannelStackDTO extends AbstractHashable
         this.spotId = spotId;
     }
 
+    @Override
+    // use all fields besides id
+    public int hashCode()
+    {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + (int) (datasetId ^ (datasetId >>> 32));
+        result = prime * result + ((column == null) ? 0 : column.hashCode());
+        result = prime * result + ((row == null) ? 0 : row.hashCode());
+        result = prime * result + (int) (spotId ^ (spotId >>> 32));
+        result = prime * result + ((t == null) ? 0 : t.hashCode());
+        result = prime * result + ((z == null) ? 0 : z.hashCode());
+        return result;
+    }
+
+    @Override
+    // use all fields besides id
+    public boolean equals(Object obj)
+    {
+        if (obj == null)
+            return false;
+        if (this == obj)
+            return true;
+        if (getClass() != obj.getClass())
+            return false;
+        ImgChannelStackDTO other = (ImgChannelStackDTO) obj;
+        if (datasetId != other.datasetId)
+            return false;
+        if (column == null)
+        {
+            if (other.column != null)
+                return false;
+        } else if (!column.equals(other.column))
+            return false;
+        if (row == null)
+        {
+            if (other.row != null)
+                return false;
+        } else if (!row.equals(other.row))
+            return false;
+        if (spotId != other.spotId)
+            return false;
+        if (t == null)
+        {
+            if (other.t != null)
+                return false;
+        } else if (!t.equals(other.t))
+            return false;
+        if (z == null)
+        {
+            if (other.z != null)
+                return false;
+        } else if (!z.equals(other.z))
+            return false;
+        return true;
+    }
+
+    @Override
+    public String toString()
+    {
+        return ToStringBuilder.reflectionToString(this,
+                ModifiedShortPrefixToStringStyle.MODIFIED_SHORT_PREFIX_STYLE);
+    }
+
 }
diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/ImgChannelStackDTOTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/ImgChannelStackDTOTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..6fa6f1e175f3817ffad83a22debc50b5bf1826a6
--- /dev/null
+++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/shared/imaging/dataaccess/ImgChannelStackDTOTest.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2010 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.openbis.plugin.screening.shared.imaging.dataaccess;
+
+import org.testng.AssertJUnit;
+import org.testng.annotations.Test;
+
+/**
+ * Tests of {@link ImgChannelStackDTO}
+ * 
+ * @author Tomasz Pylak
+ */
+@Test(groups =
+    { "screening" })
+public class ImgChannelStackDTOTest
+{
+    @Test
+    public void testEquals()
+    {
+        AssertJUnit.assertEquals(createStackChannel(), createStackChannel());
+    }
+
+    @Test
+    public void testHashCode()
+    {
+        AssertJUnit.assertEquals(createStackChannel().hashCode(), createStackChannel().hashCode());
+    }
+
+    private ImgChannelStackDTO createStackChannel()
+    {
+        return new ImgChannelStackDTO(0, 1, 1, 1, 1, 123F, null);
+    }
+}