diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceDatabaseTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceDatabaseTest.java
index 9433056259897f5d04d79baf5aae503f1b3de530..983f032c78116c2a02eb82e98d8159ed6d367168 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceDatabaseTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceDatabaseTest.java
@@ -21,8 +21,11 @@ import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
 
 import java.sql.SQLException;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -36,9 +39,11 @@ import ch.systemsx.cisd.openbis.generic.shared.IETLLIMSService;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchCriteria.MatchClauseAttribute;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetBatchUpdateDetails;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExperimentFetchOption;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExperimentFetchOptions;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewAttachment;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewExperiment;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewMaterial;
@@ -168,6 +173,88 @@ public class ETLServiceDatabaseTest extends AbstractDAOTest
         assertEquals(2, updatedSample.getParents().size());
     }
 
+    @Test
+    public void testPerformEntityOperationsUpdateDataSet()
+    {
+        // Find the samples to add
+        SearchCriteria searchCriteria = new SearchCriteria();
+        searchCriteria.addMatchClause(SearchCriteria.MatchClause.createAttributeMatch(
+                MatchClauseAttribute.TYPE, "HCS_IMAGE"));
+        searchCriteria.addMatchClause(SearchCriteria.MatchClause.createPropertyMatch("COMMENT",
+                "no comment"));
+        List<ExternalData> dataSetsToUpdate =
+                service.searchForDataSets(sessionToken, searchCriteria);
+        assertEquals(13, dataSetsToUpdate.size());
+
+        Date now = new Date();
+
+        // Update the comment
+        String newComment = "This is a new comment. This is not the old comment.";
+        List<DataSetBatchUpdatesDTO> dataSetUpdates = new ArrayList<DataSetBatchUpdatesDTO>();
+        for (ExternalData dataSetToUpdate : dataSetsToUpdate)
+        {
+            assertTrue("The modification date should be in the distant past", dataSetToUpdate
+                    .getModificationDate().compareTo(now) < 0);
+
+            String oldComment = EntityHelper.tryFindPropertyValue(dataSetToUpdate, "COMMENT");
+            assertFalse(newComment.equals(oldComment));
+            DataSetBatchUpdatesDTO updates =
+                    createDataSetUpdateDTO(dataSetToUpdate, "COMMENT", newComment);
+            dataSetUpdates.add(updates);
+        }
+
+        performDataSetUpdates(dataSetUpdates);
+
+        // Now retrieve the sample again and check that the properties were updated.
+        List<ExternalData> updatedDataSets =
+                service.searchForDataSets(sessionToken, searchCriteria);
+        // The index has not been updated yet, so we have to group the items into those that
+        // still have the old comment and those with the new comment
+
+        List<ExternalData> dataSetsWithOldValue = new ArrayList<ExternalData>();
+        List<ExternalData> dataSetsWithNewValue = new ArrayList<ExternalData>();
+        for (ExternalData data : updatedDataSets)
+        {
+            String comment = EntityHelper.tryFindPropertyValue(data, "COMMENT");
+            if (newComment.equals(comment))
+            {
+                dataSetsWithNewValue.add(data);
+            }
+        }
+
+        assertEquals(0, dataSetsWithOldValue.size());
+        assertEquals(dataSetsToUpdate.size(), dataSetsWithNewValue.size());
+
+        for (ExternalData dataSetWithNewValue : dataSetsWithNewValue)
+        {
+            assertTrue("The modification date should be current", dataSetWithNewValue
+                    .getModificationDate().compareTo(now) > 0);
+
+            String savedComment = EntityHelper.tryFindPropertyValue(dataSetWithNewValue, "COMMENT");
+            assertTrue(newComment.equals(savedComment));
+        }
+
+    }
+
+    private void performDataSetUpdates(List<DataSetBatchUpdatesDTO> dataSetUpdates)
+    {
+        TechId registrationid = new TechId(service.drawANewUniqueID(sessionToken));
+        List<NewSpace> spaceRegistrations = Collections.emptyList();
+        List<NewProject> projectRegistrations = Collections.emptyList();
+        List<NewExperiment> experimentRegistrations = Collections.emptyList();
+
+        List<SampleUpdatesDTO> sampleUpdates = Collections.emptyList();
+        List<NewSample> sampleRegistrations = Collections.emptyList();
+        Map<String, List<NewMaterial>> materialRegistrations = Collections.emptyMap();
+        List<? extends NewExternalData> dataSetRegistrations = Collections.emptyList();
+        AtomicEntityOperationDetails details =
+                new AtomicEntityOperationDetails(registrationid, null, spaceRegistrations,
+                        projectRegistrations, experimentRegistrations, sampleUpdates,
+                        sampleRegistrations, materialRegistrations, dataSetRegistrations,
+                        dataSetUpdates);
+        service.performEntityOperations(sessionToken, details);
+    }
+
     private void performSampleUpdate(Sample sampleToUpdate)
     {
         TechId registrationid = new TechId(service.drawANewUniqueID(sessionToken));
@@ -216,4 +303,28 @@ public class ETLServiceDatabaseTest extends AbstractDAOTest
         return sampleUpdate;
     }
 
+    private DataSetBatchUpdatesDTO createDataSetUpdateDTO(ExternalData dataSet,
+            String propertyCode, String propertyValue)
+    {
+        // Create the initial information
+        DataSetBatchUpdatesDTO updates = new DataSetBatchUpdatesDTO();
+        DataSetBatchUpdateDetails updateDetails = new DataSetBatchUpdateDetails();
+        updates.setDatasetCode(dataSet.getCode());
+        updates.setDatasetId(TechId.create(dataSet));
+        updates.setDetails(updateDetails);
+        updates.setVersion(dataSet.getModificationDate());
+
+        String identifierString = dataSet.getExperiment().getIdentifier();
+        ExperimentIdentifier experimentIdentifier =
+                ExperimentIdentifierFactory.parse(identifierString);
+        updates.setExperimentIdentifierOrNull(experimentIdentifier);
+
+        // Request a property update
+        EntityHelper.createOrUpdateProperty(dataSet, propertyCode, propertyValue);
+        updates.setProperties(dataSet.getProperties());
+        Set<String> propertiesToUpdate = new HashSet<String>();
+        propertiesToUpdate.add(propertyCode);
+        updateDetails.setPropertiesToUpdate(propertiesToUpdate);
+        return updates;
+    }
 }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceTest.java
index f6789af42dd1692e514161c33ce4c0fc0b4bc2c6..168fc8b30e576ee52ffc7f4870da9a3bc13833cc 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceTest.java
@@ -79,7 +79,6 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetBatchUpdatesDTO;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetShareId;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetTypePE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetUpdatesDTO;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataStorePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataStoreServerInfo;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataTypePE;
@@ -1061,7 +1060,7 @@ public class ETLServiceTest extends AbstractServerTestCase
             final MaterialTypePE materialType, final Map<String, List<NewMaterial>> newMaterials,
             final SamplePE newSamplePE, final SampleIdentifier newSampleIdentifier,
             final NewSample newSample, final NewExternalData externalData,
-            final String updatedDataSetCode, final DataSetUpdatesDTO dataSetUpdate)
+            final String updatedDataSetCode, final DataSetBatchUpdatesDTO dataSetUpdate)
     {
         context.checking(new Expectations()
             {
@@ -1154,15 +1153,21 @@ public class ETLServiceTest extends AbstractServerTestCase
         context.checking(new Expectations()
             {
                 {
-                    exactly(1).of(boFactory).createDataBO(SESSION);
-                    will(returnValue(dataBO));
+                    one(boFactory).createDataSetTable(SESSION);
+                    will(returnValue(dataSetTable));
 
                     one(entityOperationChecker).assertDataSetUpdateAllowed(SESSION,
                             Arrays.asList(dataSetUpdate));
-                    one(dataBO).update(dataSetUpdate);
-                    one(dataBO).getData();
+                    one(dataSetTable).update(Arrays.asList(dataSetUpdate));
+                    one(dataSetTable).save();
+
+                    one(dataSetTable).getDataSets();
                     final DataPE updatedDataSet = createDataSet(updatedDataSetCode, "type");
-                    will(returnValue(updatedDataSet));
+                    will(returnValue(Arrays.asList(updatedDataSet)));
+
+                    one(dataSetDAO).tryToFindFullDataSetsByCodes(Arrays.asList(updatedDataSetCode),
+                            true, false);
+                    will(returnValue(Arrays.asList(updatedDataSet)));
                 }
             });
     }