diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/ISecondaryEntityListingQuery.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/ISecondaryEntityListingQuery.java
index 536d47349807287b7684fc5bf943ec58b76bac33..11085781a622e969ef3c3bb4e2fa195c429b2f8c 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/ISecondaryEntityListingQuery.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/ISecondaryEntityListingQuery.java
@@ -24,6 +24,7 @@ import net.lemnik.eodsql.TransactionQuery;
 import ch.rinn.restrictions.Friend;
 import ch.rinn.restrictions.Private;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.LongSetMapper;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Group;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Person;
 
 /**
@@ -79,5 +80,13 @@ public interface ISecondaryEntityListingQuery extends TransactionQuery
      */
     @Select("select first_name as firstName, last_name as lastName, email, user_id as userId from persons where id=?{1}")
     public Person getPersonById(long personId);
+    
+    /**
+     * Returns all groups of this data base instance.
+     * 
+     * @param databaseInstanceId The id of the ddatabase to get the groups for.
+     */
+    @Select("select id, code from groups where dbin_id=?{1}")
+    public Group[] getAllGroups(long databaseInstanceId);
 
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/SecondaryEntityDAO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/SecondaryEntityDAO.java
index a717b239f39d30c319b220241621287ba9677699..487b112584c17d1ae648c6fac12c471d37f7a5eb 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/SecondaryEntityDAO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/SecondaryEntityDAO.java
@@ -23,6 +23,8 @@ import it.unimi.dsi.fastutil.longs.LongSet;
 
 import java.sql.Connection;
 
+import org.springframework.dao.EmptyResultDataAccessException;
+
 import net.lemnik.eodsql.DataIterator;
 import net.lemnik.eodsql.QueryTool;
 
@@ -64,13 +66,13 @@ public class SecondaryEntityDAO
         Connection connection = DatabaseContextUtils.getConnection(daoFactory);
         ISecondaryEntityListingQuery query =
                 QueryTool.getQuery(connection, ISecondaryEntityListingQuery.class);
-        return create(daoFactory, query);
+        return create(daoFactory.getHomeDatabaseInstance(), query);
     }
 
     @Private
-    static SecondaryEntityDAO create(IDAOFactory daoFactory, ISecondaryEntityListingQuery query)
+    public static SecondaryEntityDAO create(DatabaseInstancePE homeDatabaseInstance,
+            ISecondaryEntityListingQuery query)
     {
-        DatabaseInstancePE homeDatabaseInstance = daoFactory.getHomeDatabaseInstance();
         return new SecondaryEntityDAO(query, homeDatabaseInstance);
     }
 
@@ -89,6 +91,10 @@ public class SecondaryEntityDAO
     {
         final ExperimentProjectGroupCodeRecord record =
                 query.getExperimentAndProjectAndGroupCodeForId(experimentId);
+        if (record == null)
+        {
+            throw new EmptyResultDataAccessException(1);
+        }
         return createExperiment(experimentId, record);
     }
 
@@ -117,6 +123,10 @@ public class SecondaryEntityDAO
     public Person getPerson(long personId)
     {
         Person registrator = query.getPersonById(personId);
+        if (registrator == null)
+        {
+            throw new EmptyResultDataAccessException(1);
+        }
         registrator.setUserId(escapeHtml(registrator.getUserId()));
         registrator.setEmail(escapeHtml(registrator.getEmail()));
         registrator.setFirstName(escapeHtml(registrator.getFirstName()));
@@ -124,6 +134,11 @@ public class SecondaryEntityDAO
         return registrator;
     }
 
+    public Group[] getAllGroups(long databaseInstanceId)
+    {
+        return query.getAllGroups(databaseInstanceId);
+    }
+
     // TODO 2009-09-01, Tomasz Pylak: implement a version for h2
     public Long2ObjectMap<Sample> getSamples(LongSet sampleIds)
     {
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/ISampleListingFullQuery.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/ISampleListingFullQuery.java
index 44f14af8d4ec0c7ce1a0ac498f45c4cf96347862..b2582539b8a45aea3ef83cbc87d7318917d21ef4 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/ISampleListingFullQuery.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/ISampleListingFullQuery.java
@@ -51,7 +51,7 @@ public interface ISampleListingFullQuery extends ISampleListingQuery
      * <p>
      * <em>Do not call directly, call via {@link ISampleSetListingQuery}</em>
      */
-    @Select(sql = "select s.id, s.perm_id, s.code, s.expe_id, "
+    @Select(sql = "select s.id, s.perm_id, s.code, s.expe_id, s.grou_id, "
             + "       s.registration_timestamp, s.pers_id_registerer, "
             + "       s.samp_id_generated_from, s.samp_id_part_of, s.saty_id, s.inva_id "
             + "   from samples s where s.id = any(?{1})", parameterBindings =
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/ISampleListingQuery.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/ISampleListingQuery.java
index 8508f15077a17033b76c7c10369c22ccd3190008..10f3c1dab3c4f9748e2dd3b9a0f8d436bed9f72f 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/ISampleListingQuery.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/ISampleListingQuery.java
@@ -62,7 +62,7 @@ public interface ISampleListingQuery extends TransactionQuery, IPropertyListingQ
     /**
      * Returns the sample for the given <var>sampleId</var>.
      */
-    @Select("select s.id, s.perm_id, s.code, s.expe_id, "
+    @Select("select s.id, s.perm_id, s.code, s.expe_id, s.grou_id, "
             + "       s.registration_timestamp, s.pers_id_registerer, "
             + "       s.samp_id_generated_from, s.samp_id_part_of, s.saty_id, s.inva_id "
             + "   from samples s where s.id=?{1}")
@@ -71,7 +71,7 @@ public interface ISampleListingQuery extends TransactionQuery, IPropertyListingQ
     /**
      * Returns all samples in the database.
      */
-    @Select(sql = "select s.id, s.perm_id, s.code, s.expe_id, "
+    @Select(sql = "select s.id, s.perm_id, s.code, s.expe_id, s.grou_id, "
             + "       s.registration_timestamp, s.pers_id_registerer, "
             + "       s.samp_id_generated_from, s.samp_id_part_of, s.saty_id, s.inva_id "
             + "   from samples s left join groups g on s.grou_id=g.id where s.dbin_id=?{1} or g.dbin_id=?{1}", fetchSize = FETCH_SIZE)
@@ -149,7 +149,7 @@ public interface ISampleListingQuery extends TransactionQuery, IPropertyListingQ
     /**
      * Returns the samples for the given <var>sampleContainerId</var>.
      */
-    @Select(sql = "select s.id, s.perm_id, s.code, s.expe_id, "
+    @Select(sql = "select s.id, s.perm_id, s.code, s.expe_id, s.grou_id, "
             + "       s.registration_timestamp, s.pers_id_registerer, "
             + "       s.samp_id_generated_from, s.samp_id_part_of, s.saty_id, s.inva_id "
             + "   from samples s where s.samp_id_part_of=?{1}", fetchSize = FETCH_SIZE)
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/SampleListingWorker.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/SampleListingWorker.java
index 7ea174321f8d695e7336d23b6f3275ff6795ebf9..65036727aae1c4c7a00c385b7f2eb5a4a3ade69b 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/SampleListingWorker.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/SampleListingWorker.java
@@ -152,6 +152,8 @@ final class SampleListingWorker
     private int maxSampleContainerResolutionDepth;
 
     private final Long2ObjectMap<Sample> sampleMap = new Long2ObjectOpenHashMap<Sample>();
+    
+    private final Long2ObjectMap<Group> groupMap = new Long2ObjectOpenHashMap<Group>();
 
     public static SampleListingWorker create(ListOrSearchSampleCriteria criteria,
             String baseIndexURL, SampleListerDAO dao, SecondaryEntityDAO referencedEntityDAO)
@@ -204,13 +206,29 @@ final class SampleListingWorker
         final StopWatch watch = new StopWatch();
         watch.start();
         final Experiment expOrNull = tryLoadExperiment();
-        final Group groupOrNull = tryLoadGroup(expOrNull);
+        final boolean oneGroupPerSample = isOneGroupPerSamples();
+        final Group groupOrNull;
+        if (oneGroupPerSample)
+        {
+            groupOrNull = null;
+            final Group[] groups = referencedEntityDAO.getAllGroups(databaseInstanceId);
+            for (Group group : groups)
+            {
+                groupMap.put(group.getId(), group);
+            }
+        } else
+        {
+            groupOrNull = tryLoadGroup(expOrNull);
+        }
         loadSampleTypes();
-        retrievePrimaryBasicSamples(tryGetIteratorForSamplesByIds(), groupOrNull);
-        retrievePrimaryBasicSamples(tryGetIteratorForGroupSamples(), groupOrNull);
-        retrievePrimaryBasicSamples(tryGetIteratorForSharedSamples(), groupOrNull);
-        retrievePrimaryBasicSamples(tryGetIteratorForExperimentSamples(), groupOrNull);
-        retrievePrimaryBasicSamples(tryGetIteratorForContainedSamples(), groupOrNull);
+        retrievePrimaryBasicSamples(tryGetIteratorForSamplesByIds(), groupOrNull, oneGroupPerSample);
+        retrievePrimaryBasicSamples(tryGetIteratorForGroupSamples(), groupOrNull, oneGroupPerSample);
+        retrievePrimaryBasicSamples(tryGetIteratorForSharedSamples(), groupOrNull,
+                oneGroupPerSample);
+        retrievePrimaryBasicSamples(tryGetIteratorForExperimentSamples(), groupOrNull,
+                oneGroupPerSample);
+        retrievePrimaryBasicSamples(tryGetIteratorForContainedSamples(), groupOrNull,
+                oneGroupPerSample);
         if (operationLog.isDebugEnabled())
         {
             watch.stop();
@@ -268,6 +286,11 @@ final class SampleListingWorker
         return experiment;
     }
 
+    private boolean isOneGroupPerSamples()
+    {
+        return criteria.getContainerSampleId() != null || criteria.getSampleIds() != null;
+    }
+
     private Group tryLoadGroup(final Experiment expOrNull)
     {
         if (criteria.isIncludeGroup() == false && expOrNull == null)
@@ -405,21 +428,22 @@ final class SampleListingWorker
     }
 
     private void retrievePrimaryBasicSamples(final Iterable<SampleRecord> sampleIteratorOrNull,
-            final Group groupOrNull)
+            final Group groupOrNull, final boolean oneGroupPerSample)
     {
         assert sampleList != null;
 
-        retrieveBasicSamples(sampleIteratorOrNull, groupOrNull, baseIndexURL, sampleList);
+        retrieveBasicSamples(sampleIteratorOrNull, groupOrNull, baseIndexURL, sampleList,
+                oneGroupPerSample);
     }
 
     private void retrieveDependentBasicSamples(final Iterable<SampleRecord> sampleIteratorOrNull)
     {
-        retrieveBasicSamples(sampleIteratorOrNull, null, null, null);
+        retrieveBasicSamples(sampleIteratorOrNull, null, null, null, false);
     }
 
     private void retrieveBasicSamples(final Iterable<SampleRecord> sampleIteratorOrNull,
             final Group groupOrNull, final String baseIndexURLOrNull,
-            final List<Sample> sampleListOrNull)
+            final List<Sample> sampleListOrNull, final boolean oneGroupPerSample)
     {
         if (sampleIteratorOrNull == null)
         {
@@ -428,7 +452,9 @@ final class SampleListingWorker
         final boolean primarySample = (sampleListOrNull != null);
         for (SampleRecord row : sampleIteratorOrNull)
         {
-            final Sample sample = createSample(row, groupOrNull, baseIndexURLOrNull, primarySample);
+            final Sample sample =
+                    createSample(row, groupOrNull, oneGroupPerSample, baseIndexURLOrNull,
+                            primarySample);
             sampleMap.put(sample.getId(), sample);
             if (sampleListOrNull != null)
             {
@@ -438,7 +464,8 @@ final class SampleListingWorker
     }
 
     private Sample createSample(SampleRecord row, final Group groupOrNull,
-            final String baseIndexURLOrNull, final boolean primarySample)
+            final boolean oneGroupPerSample, final String baseIndexURLOrNull,
+            final boolean primarySample)
     {
         final Sample sample = new Sample();
         sample.setId(row.id);
@@ -447,18 +474,22 @@ final class SampleListingWorker
         sample.setSampleType(sampleTypes.get(row.saty_id));
         if (primarySample)
         {
-            if (groupOrNull != null)
+            if (oneGroupPerSample)
             {
-                sample.setGroup(groupOrNull);
-                final GroupIdentifier groupId =
-                        new GroupIdentifier(databaseInstance.getCode(), groupOrNull.getCode());
-                sample.setIdentifier(new SampleIdentifier(groupId, sample.getCode()).toString());
+                if (row.grou_id == null)
+                {
+                    setDatabaseInstance(sample);
+                }
+                else {
+                    setGroup(sample, groupMap.get(row.grou_id));
+                }
+            }
+            else if (groupOrNull != null)
+            {
+                setGroup(sample, groupOrNull);
             } else
             {
-                sample.setDatabaseInstance(databaseInstance);
-                final DatabaseInstanceIdentifier dbId =
-                        new DatabaseInstanceIdentifier(databaseInstance.getCode());
-                sample.setIdentifier(new SampleIdentifier(dbId, sample.getCode()).toString());
+                setDatabaseInstance(sample);
             }
             sample.setPermId(StringEscapeUtils.escapeHtml(row.perm_id));
             sample.setPermlink(PermlinkUtilities.createPermlinkURL(baseIndexURLOrNull,
@@ -499,6 +530,24 @@ final class SampleListingWorker
         return sample;
     }
 
+    private void setGroup(final Sample sample, final Group group)
+    {
+        sample.setGroup(group);
+        final GroupIdentifier groupId =
+                new GroupIdentifier(databaseInstance.getCode(), group.getCode());
+        sample
+                .setIdentifier(new SampleIdentifier(groupId, sample.getCode())
+                        .toString());
+    }
+
+    private void setDatabaseInstance(final Sample sample)
+    {
+        sample.setDatabaseInstance(databaseInstance);
+        final DatabaseInstanceIdentifier dbId =
+                new DatabaseInstanceIdentifier(databaseInstance.getCode());
+        sample.setIdentifier(new SampleIdentifier(dbId, sample.getCode()).toString());
+    }
+
     private void addToRequested(long newId, long oldId, int initialDepth, boolean primarySample)
     {
         if (primarySample)
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/SampleRecord.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/SampleRecord.java
index 58b9b2e30e33118349129995f485ef67dace2593..851589b0f2020fe59c5b956b762c543e6e8a39f1 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/SampleRecord.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/SampleRecord.java
@@ -30,6 +30,8 @@ public class SampleRecord extends CodeRecord
     public String perm_id;
 
     public Long expe_id;
+    
+    public Long grou_id;
 
     public Long samp_id_generated_from;
 
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/SecondaryEntityListingQueryTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/SecondaryEntityListingQueryTest.java
index 30bb59292eb246f1fd52211fda30d455bff617b0..a9a3173ed4ecf8658d510a609a4dc946499cdf1f 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/SecondaryEntityListingQueryTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/common/entity/SecondaryEntityListingQueryTest.java
@@ -65,7 +65,7 @@ public class SecondaryEntityListingQueryTest extends AbstractDAOTest
     {
         ISecondaryEntityListingQuery query =
                 EntityListingTestUtils.createQuery(daoFactory, ISecondaryEntityListingQuery.class);
-        return SecondaryEntityDAO.create(daoFactory, query);
+        return SecondaryEntityDAO.create(daoFactory.getHomeDatabaseInstance(), query);
     }
 
     @Test
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/SampleListingWorkerTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/SampleListingWorkerTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..0c165e994798cb6ea13f4ea9498b6cffb3585830
--- /dev/null
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/samplelister/SampleListingWorkerTest.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2009 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.generic.server.business.bo.samplelister;
+
+import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
+import it.unimi.dsi.fastutil.longs.LongSet;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.openbis.generic.server.business.bo.common.entity.SecondaryEntityDAO;
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.AbstractDAOTest;
+import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ListOrSearchSampleCriteria;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ListSampleCriteria;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample;
+
+import static org.testng.AssertJUnit.*;
+
+/**
+ * Test cases for the {@link SampleListingWorker}.
+ * 
+ * @author Bernd Rinn
+ */
+public class SampleListingWorkerTest extends AbstractDAOTest
+{
+
+    private final String BASE_INDEX_URL = "baseIndexURL";
+
+    private SampleListerDAO sampleListerDAO;
+
+    private SecondaryEntityDAO secondaryDAO;
+
+    @BeforeMethod
+    public void beforeMethod()
+    {
+        sampleListerDAO = SampleListingQueryTest.createSampleListerDAO(daoFactory);
+        secondaryDAO = SecondaryEntityDAO.create(daoFactory);
+    }
+
+    @Test
+    public void testListSamplesByIdGroupNotNull()
+    {
+        final LongSet sampleIds = new LongOpenHashSet();
+        sampleIds.addAll(Arrays.asList(1L, 2L, 3L));
+        final ListOrSearchSampleCriteria criteria = new ListOrSearchSampleCriteria(sampleIds);
+        final SampleListingWorker worker =
+                SampleListingWorker.create(criteria, BASE_INDEX_URL, sampleListerDAO, secondaryDAO);
+        final List<Sample> list = worker.load();
+        assertTrue(list.size() > 0);
+        for (Sample s : list)
+        {
+            assertNotNull("ID:" + s.getId(), s.getGroup());
+        }
+    }
+
+    @Test
+    public void testListSamplesForContainerGroupNotNull()
+    {
+        final ListSampleCriteria baseCriteria =
+                ListSampleCriteria.createForContainer(new TechId(997L));
+        final ListOrSearchSampleCriteria criteria = new ListOrSearchSampleCriteria(baseCriteria);
+        final SampleListingWorker worker =
+                SampleListingWorker.create(criteria, BASE_INDEX_URL, sampleListerDAO, secondaryDAO);
+        final List<Sample> list = worker.load();
+        assertTrue(list.size() > 0);
+        for (Sample s : list)
+        {
+            assertNotNull("ID:" + s.getId(), s.getGroup());
+        }
+    }
+
+    @Test
+    public void testListSamplesForExperimentGroupNotNull()
+    {
+        final ListSampleCriteria baseCriteria =
+                ListSampleCriteria.createForExperiment(new TechId(2L));
+        final ListOrSearchSampleCriteria criteria = new ListOrSearchSampleCriteria(baseCriteria);
+        final SampleListingWorker worker =
+                SampleListingWorker.create(criteria, BASE_INDEX_URL, sampleListerDAO, secondaryDAO);
+        final List<Sample> list = worker.load();
+        assertTrue(list.size() > 0);
+        for (Sample s : list)
+        {
+            assertNotNull("ID:" + s.getId(), s.getGroup());
+        }
+    }
+}