diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractSampleBusinessObject.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractSampleBusinessObject.java
index b59329d8cada9e899a2c9277db3c42b0b11bbfdc..6782ed2b31e187cb277e49b9e0933db829e53f27 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractSampleBusinessObject.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractSampleBusinessObject.java
@@ -214,7 +214,6 @@ abstract class AbstractSampleBusinessObject extends AbstractSampleIdentifierBusi
         final Set<SamplePE> parentPEs = new HashSet<SamplePE>();
         for (SampleIdentifier si : parentIdentifiers)
         {
-            // TODO 2010-11-10, Piotr Buczek: use cache
             SamplePE parent = getSampleByIdentifier(si);
             parentPEs.add(parent);
         }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractSampleIdentifierBusinessObject.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractSampleIdentifierBusinessObject.java
index b504e0c0ffba7fbc15a414dca287bf4b24008f2f..bc2e7eb3f840f8c601e1497cceea9b80808e60ff 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractSampleIdentifierBusinessObject.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractSampleIdentifierBusinessObject.java
@@ -16,6 +16,9 @@
 
 package ch.systemsx.cisd.openbis.generic.server.business.bo;
 
+import java.util.HashMap;
+import java.util.Map;
+
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.util.SampleOwner;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.util.SampleOwnerFinder;
@@ -35,6 +38,9 @@ import ch.systemsx.cisd.openbis.generic.shared.util.HibernateUtils;
  */
 abstract class AbstractSampleIdentifierBusinessObject extends AbstractBusinessObject
 {
+    private final Map<SampleIdentifier, SamplePE> sampleByIdentifierCache =
+            new HashMap<SampleIdentifier, SamplePE>();
+
     private final SampleOwnerFinder sampleOwnerFinder;
 
     AbstractSampleIdentifierBusinessObject(final IDAOFactory daoFactory, final Session session)
@@ -70,27 +76,35 @@ abstract class AbstractSampleIdentifierBusinessObject extends AbstractBusinessOb
 
     protected SamplePE tryToGetSampleByIdentifier(final SampleIdentifier sampleIdentifier)
     {
-        // TODO 2010-11-10, Piotr Buczek: use cache
         assert sampleIdentifier != null : "Sample identifier unspecified.";
-        final SampleOwner sampleOwner = sampleOwnerFinder.figureSampleOwner(sampleIdentifier);
-        final String sampleCode = sampleIdentifier.getSampleCode();
-        final ISampleDAO sampleDAO = getSampleDAO();
-        final SamplePE sample;
-        if (sampleOwner.isDatabaseInstanceLevel())
+
+        final SamplePE cachedResult = sampleByIdentifierCache.get(sampleIdentifier);
+        if (cachedResult != null)
         {
-            sample =
-                    sampleDAO.tryFindByCodeAndDatabaseInstance(sampleCode,
-                            sampleOwner.tryGetDatabaseInstance());
+            return cachedResult;
         } else
         {
-            assert sampleOwner.isGroupLevel() : "Must be of space level.";
-            sample = sampleDAO.tryFindByCodeAndGroup(sampleCode, sampleOwner.tryGetGroup());
+            final SampleOwner sampleOwner = sampleOwnerFinder.figureSampleOwner(sampleIdentifier);
+            final String sampleCode = sampleIdentifier.getSampleCode();
+            final ISampleDAO sampleDAO = getSampleDAO();
+            final SamplePE result;
+            if (sampleOwner.isDatabaseInstanceLevel())
+            {
+                result =
+                        sampleDAO.tryFindByCodeAndDatabaseInstance(sampleCode,
+                                sampleOwner.tryGetDatabaseInstance());
+            } else
+            {
+                assert sampleOwner.isGroupLevel() : "Must be of space level.";
+                result = sampleDAO.tryFindByCodeAndGroup(sampleCode, sampleOwner.tryGetGroup());
+            }
+            if (result != null)
+            {
+                HibernateUtils.initialize(result.getExperiment());
+                sampleByIdentifierCache.put(sampleIdentifier, result);
+            }
+            return result;
         }
-        if (sample != null)
-        {
-            HibernateUtils.initialize(sample.getExperiment());
-        }
-        return sample;
     }
 
     /**