diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServiceProvider.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServiceProvider.java
index 08cd1d4d51aa854d5b1d2ee3ffd22058be38e978..84e9dffc79a447376304c0bbced7910787d32934 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServiceProvider.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServiceProvider.java
@@ -16,6 +16,7 @@
 
 package ch.systemsx.cisd.openbis.generic.server;
 
+import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.DAOFactory;
 import ch.systemsx.cisd.openbis.generic.shared.ISessionWorkspaceProvider;
 import ch.systemsx.cisd.openbis.generic.shared.SessionWorkspaceProvider;
 import org.springframework.context.ApplicationContext;
@@ -41,6 +42,8 @@ public class CommonServiceProvider
 {
     private static ApplicationContext applicationContext;
 
+    private static IDAOFactory daoFactory;
+
     public static void setApplicationContext(ApplicationContext context)
     {
         applicationContext = context;
@@ -63,7 +66,15 @@ public class CommonServiceProvider
 
     public static IDAOFactory getDAOFactory()
     {
-        return (IDAOFactory) applicationContext.getBean("dao-factory");
+        if (daoFactory == null) {
+            daoFactory = (IDAOFactory) applicationContext.getBean("dao-factory");
+        }
+        return daoFactory;
+    }
+
+    public static void setDAOFactory(IDAOFactory daoFactory)
+    {
+        CommonServiceProvider.daoFactory = daoFactory;
     }
 
     public static ICommonBusinessObjectFactory getBusinessObjectFactory()
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/AbstractServerTestCase.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/AbstractServerTestCase.java
index d64f4c9160dea5cc97a5411ac9ab2051c0acda3e..56bacd2ce4fdc7b2221a8bc109cb35dfd02bd81e 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/AbstractServerTestCase.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/AbstractServerTestCase.java
@@ -19,6 +19,8 @@ package ch.systemsx.cisd.openbis.generic.shared;
 import java.util.ArrayList;
 import java.util.Arrays;
 
+import ch.systemsx.cisd.openbis.generic.server.CommonServiceProvider;
+import ch.systemsx.cisd.openbis.generic.shared.dto.*;
 import org.apache.log4j.Level;
 import org.jmock.Expectations;
 import org.jmock.Mockery;
@@ -84,15 +86,6 @@ import ch.systemsx.cisd.openbis.generic.server.dataaccess.PersistencyResources;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.IPermIdDAO;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DisplaySettings;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewExperiment;
-import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetTypePE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.DataStorePE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentTypePE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.PersonPE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectPE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.Session;
-import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE;
 import ch.systemsx.cisd.openbis.generic.shared.util.MaterialConfigurationProvider;
 import ch.systemsx.cisd.openbis.util.LogRecordingUtils;
 
@@ -134,6 +127,8 @@ public abstract class AbstractServerTestCase extends AssertJUnit
 
     protected ISampleDAO sampleDAO;
 
+    protected ISampleRelationshipDAO sampleRelationshipDAO;
+
     protected ISpaceBO spaceBO;
 
     protected ISampleBO sampleBO;
@@ -236,10 +231,12 @@ public abstract class AbstractServerTestCase extends AssertJUnit
         propertiesBatchManager = context.mock(IPropertiesBatchManager.class);
         // DAO
         daoFactory = context.mock(IDAOFactory.class);
+        CommonServiceProvider.setDAOFactory(daoFactory);
         personDAO = context.mock(IPersonDAO.class);
         groupDAO = context.mock(ISpaceDAO.class);
         spaceDAO = groupDAO;
         sampleDAO = context.mock(ISampleDAO.class);
+        sampleRelationshipDAO = context.mock(ISampleRelationshipDAO.class);
         roleAssignmentDAO = context.mock(IRoleAssignmentDAO.class);
         dataSetDAO = context.mock(IDataDAO.class);
         permIdDAO = context.mock(IPermIdDAO.class);
@@ -298,6 +295,8 @@ public abstract class AbstractServerTestCase extends AssertJUnit
                     will(returnValue(groupDAO));
                     allowing(daoFactory).getSampleDAO();
                     will(returnValue(sampleDAO));
+                    allowing(daoFactory).getSampleRelationshipDAO();
+                    will(returnValue(sampleRelationshipDAO));
                     allowing(daoFactory).getExperimentDAO();
                     will(returnValue(experimentDAO));
                     allowing(daoFactory).getRoleAssignmentDAO();
diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/dss/reporting-plugins/exports-api/exportsApi.py b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/dss/reporting-plugins/exports-api/exportsApi.py
index 5c4fd14cc39983a3a196f9149f37ba6ffbc82570..9565d715b0f63b16145540dc4d72e7e83d6f5ef4 100644
--- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/dss/reporting-plugins/exports-api/exportsApi.py
+++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/dss/reporting-plugins/exports-api/exportsApi.py
@@ -151,10 +151,12 @@ def validateDataSize(entitiesToExport, tr):
             estimatedSizeInBytes += 12000;  # AVG File Metadata size
     estimatedSizeInMegabytes = estimatedSizeInBytes / 1000000;
     operationLog.info(
-        "Size Limit check - limitDataSizeInBytes: " + str(limitDataSizeInBytes) + " > " + " estimatedSizeInBytes: " + str(estimatedSizeInBytes));
+        u"Size Limit check - limitDataSizeInBytes: " + str(limitDataSizeInBytes).encode('utf-8') +
+        u" > estimatedSizeInBytes: " + str(estimatedSizeInBytes).encode('utf-8'));
     if estimatedSizeInBytes > limitDataSizeInBytes:
-        raise UserFailureException("The selected data is " + str(estimatedSizeInMegabytes) + " MB that is bigger than the configured limit of " + str(
-            limitDataSizeInMegabytes) + " MB");
+        raise UserFailureException(u"The selected data is " + estimatedSizeInMegabytes +
+                                   u" MB that is bigger than the configured limit of " +
+                                   limitDataSizeInMegabytes + u" MB");
 
 
 def findEntitiesToExport(params):
@@ -172,17 +174,17 @@ def findEntitiesToExport(params):
         if entity.get("expand"):
             entitiesToExpand.append(entityAsPythonMap);
 
-    operationLog.info("Found %d entities to expand." % len(entitiesToExpand))
+    operationLog.info(u"Found %d entities to expand." % len(entitiesToExpand))
     while entitiesToExpand:
         entityToExpand = entitiesToExpand.popleft();
         type = entityToExpand["type"];
         permId = entityToExpand["permId"];
-        operationLog.info("Expanding type: " + str(type) + " permId: " + str(permId));
+        operationLog.info(u"Expanding type: " + type.encode("utf-8") + u" permId: " + permId.encode("utf-8"));
 
         if type == "ROOT":
             criteria = SpaceSearchCriteria();
             results = v3.searchSpaces(sessionToken, criteria, SpaceFetchOptions());
-            operationLog.info("Found: " + str(results.getTotalCount()) + " spaces");
+            operationLog.info(u"Found: %d spaces" % results.getTotalCount());
             for space in results.getObjects():
                 entityFound = {"type": "SPACE", "permId": space.getCode(), "registrationDate": space.getRegistrationDate()};
                 addToExportWithoutRepeating(entitiesToExport, entityFound);
@@ -191,7 +193,7 @@ def findEntitiesToExport(params):
             criteria = ProjectSearchCriteria();
             criteria.withSpace().withCode().thatEquals(permId);
             results = v3.searchProjects(sessionToken, criteria, ProjectFetchOptions());
-            operationLog.info("Found: " + str(results.getTotalCount()) + " projects");
+            operationLog.info(u"Found: %d projects" % results.getTotalCount());
             for project in results.getObjects():
                 entityFound = {"type": "PROJECT", "permId": project.getPermId().getPermId(), "registrationDate": project.getRegistrationDate()};
                 addToExportWithoutRepeating(entitiesToExport, entityFound);
@@ -200,7 +202,7 @@ def findEntitiesToExport(params):
             criteria = ExperimentSearchCriteria();
             criteria.withProject().withPermId().thatEquals(permId);
             results = v3.searchExperiments(sessionToken, criteria, ExperimentFetchOptions());
-            operationLog.info("Found: " + str(results.getTotalCount()) + " experiments");
+            operationLog.info(u"Found: %d experiments" % results.getTotalCount());
             for experiment in results.getObjects():
                 entityFound = {"type": "EXPERIMENT", "permId": experiment.getPermId().getPermId(),
                                "registrationDate": experiment.getRegistrationDate()};
@@ -210,7 +212,7 @@ def findEntitiesToExport(params):
             criteria = SampleSearchCriteria();
             criteria.withExperiment().withPermId().thatEquals(permId);
             results = v3.searchSamples(sessionToken, criteria, SampleFetchOptions());
-            operationLog.info("Found: " + str(results.getTotalCount()) + " samples");
+            operationLog.info(u"Found: %d samples" % results.getTotalCount());
 
             dCriteria = DataSetSearchCriteria();
             dCriteria.withExperiment().withPermId().thatEquals(permId);
@@ -218,13 +220,13 @@ def findEntitiesToExport(params):
             fetchOptions = DataSetFetchOptions()
             fetchOptions.withDataStore()
             dResults = v3.searchDataSets(sessionToken, dCriteria, fetchOptions);
-            operationLog.info("Found: " + str(dResults.getTotalCount()) + " datasets");
+            operationLog.info(u"Found: %d datasets" % dResults.getTotalCount());
             for dataset in dResults.getObjects():
                 entityFound = {"type": "DATASET", "permId": dataset.getPermId().getPermId(), "registrationDate": dataset.getRegistrationDate()};
                 addToExportWithoutRepeating(entitiesToExport, entityFound);
                 entitiesToExpand.append(entityFound);
 
-            operationLog.info("Found: " + str(results.getTotalCount()) + " samples");
+            operationLog.info(u"Found: %d samples" % results.getTotalCount());
             for sample in results.getObjects():
                 entityFound = {"type": "SAMPLE", "permId": sample.getPermId().getPermId(), "registrationDate": sample.getRegistrationDate()};
                 addToExportWithoutRepeating(entitiesToExport, entityFound);
@@ -235,7 +237,7 @@ def findEntitiesToExport(params):
             fetchOptions = DataSetFetchOptions()
             fetchOptions.withDataStore()
             results = v3.searchDataSets(sessionToken, criteria, fetchOptions);
-            operationLog.info("Found: " + str(results.getTotalCount()) + " datasets");
+            operationLog.info(u"Found: %d datasets" % results.getTotalCount());
             for dataset in results.getObjects():
                 entityFound = {"type": "DATASET", "permId": dataset.getPermId().getPermId(), "registrationDate": dataset.getRegistrationDate()};
                 addToExportWithoutRepeating(entitiesToExport, entityFound);
@@ -244,7 +246,7 @@ def findEntitiesToExport(params):
             criteria = DataSetFileSearchCriteria();
             criteria.withDataSet().withPermId().thatEquals(permId);
             results = v3d.searchFiles(sessionToken, criteria, DataSetFileFetchOptions());
-            operationLog.info("Found: " + str(results.getTotalCount()) + " files");
+            operationLog.info(u"Found: %d files" % results.getTotalCount());
             for file in results.getObjects():
                 entityFound = {"type": "FILE", "permId": permId, "path": file.getPath(), "isDirectory": file.isDirectory(),
                                "length": file.getFileLength()};
@@ -282,7 +284,7 @@ def generateFilesInZip(zos, entities, includeRoot, sessionToken, tempDirPath, de
     for entity in entities:
         type = entity["type"];
         permId = entity["permId"];
-        operationLog.info("exporting type: " + str(type) + " permId: " + str(permId));
+        operationLog.info(u"exporting type: " + type.encode("utf-8") + u" permId: " + permId.encode("utf-8"));
         entityObj = None;
         entityFilePath = None;
 
@@ -383,8 +385,7 @@ def generateFilesInZip(zos, entities, includeRoot, sessionToken, tempDirPath, de
         if entityObj is not None:
             objectCache[permId] = entityObj;
 
-        operationLog.info("--> Entity type: " + type + " permId: " + permId + " obj: " + str(entityObj is not None) + " path: " + str(
-            entityFilePath) + " before files.");
+        operationLog.info(u"--> Entity type: %s permId: %s obj: %s path: %s before files." % (type, permId, str(entityObj is not None), entityFilePath));
         if entityObj is not None and entityFilePath is not None:
             # JSON
             entityJson = String(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(entityObj));
@@ -403,19 +404,20 @@ def generateFilesInZip(zos, entities, includeRoot, sessionToken, tempDirPath, de
             entityHTML = getDOCX(entityObj, v3, sessionToken, True);
             fileMetadatum = addFile(tempDirPath, entityFilePath, "html", entityHTML, zos, deflated=deflated);
             fileMetadata.append(fileMetadatum)
-            operationLog.info("--> Entity type: " + type + " permId: " + permId + " post html.");
+            operationLog.info(u"--> Entity type: " + type.encode("utf-8") + u" permId: " + permId.encode("utf-8") +
+                              u" post html.");
     if emptyZip:
-        raise IOError('Nothing added to ZIP file.')
+        raise IOError("Nothing added to ZIP file.")
     return fileMetadata
 
 
 def generateDownloadUrl(sessionToken, tempZipFileName, tempZipFilePath):
     # Store on workspace to be able to generate a download link
-    operationLog.info("Zip file can be found on the temporal directory: " + tempZipFilePath);
+    operationLog.info(u"Zip file can be found on the temporal directory: " + tempZipFilePath.encode("utf-8"));
     dssService = ServiceProvider.getApplicationContext().getBean("dss-service-rpc-generic")
     dssService.putFileToSessionWorkspace(sessionToken, tempZipFileName, FileInputStream(File(tempZipFilePath)))
     tempZipFileWorkspaceURL = DataStoreServer.getConfigParameters().getDownloadURL() + "/datastore_server/session_workspace_file_download?sessionID=" + sessionToken + "&filePath=" + tempZipFileName;
-    operationLog.info("Zip file can be downloaded from the workspace: " + tempZipFileWorkspaceURL);
+    operationLog.info(u"Zip file can be downloaded from the workspace: " + tempZipFileWorkspaceURL.encode("utf-8"));
     return tempZipFileWorkspaceURL
 
 
diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServerTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServerTest.java
index 1764ec8a2206d80f64199519c33efca7ff044109..b2275e71fd544855dca5106641563683170beaa5 100644
--- a/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServerTest.java
+++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/ScreeningServerTest.java
@@ -17,6 +17,8 @@
 package ch.systemsx.cisd.openbis.plugin.screening.server;
 
 import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.List;
 
 import org.jmock.Expectations;
 import org.testng.annotations.AfterMethod;
@@ -113,6 +115,8 @@ public class ScreeningServerTest extends AbstractServerTestCase
                     one(sampleBO).loadBySamplePermId(PERM_ID);
                     one(sampleBO).getSample();
                     will(returnValue(exampleSample));
+                    one(sampleRelationshipDAO).listSampleParents(List.of(exampleSample.getId()));
+                    will(returnValue(List.of()));
                 }
             });
 
@@ -143,6 +147,8 @@ public class ScreeningServerTest extends AbstractServerTestCase
                             SampleIdentifierFactory.parse(SAMPLE_IDENTIFIER));
                     one(sampleBO).getSample();
                     will(returnValue(exampleSample));
+                    one(sampleRelationshipDAO).listSampleParents(List.of(exampleSample.getId()));
+                    will(returnValue(List.of()));
                 }
             });
 
diff --git a/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningApiImplTest.java b/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningApiImplTest.java
index 3a9b3f4fdae0c1e078ddb57ad65396b5861ec012..e4968defbf2b8d08e8b43c5d314afa966775a00d 100644
--- a/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningApiImplTest.java
+++ b/screening/sourceTest/java/ch/systemsx/cisd/openbis/plugin/screening/server/logic/ScreeningApiImplTest.java
@@ -102,6 +102,8 @@ public class ScreeningApiImplTest extends AbstractServerTestCase
                     one(sampleBO).loadBySampleIdentifier(SampleIdentifierFactory.parse(identifier));
                     one(sampleBO).getSample();
                     will(returnValue(plate));
+                    one(sampleRelationshipDAO).listSampleParents(List.of(plate.getId()));
+                    will(returnValue(List.of()));
 
                     one(screeningBOFactory).createSampleLister(session);
                     will(returnValue(sampleLister));
@@ -139,6 +141,8 @@ public class ScreeningApiImplTest extends AbstractServerTestCase
                     one(sampleBO).loadBySamplePermId(permId);
                     one(sampleBO).getSample();
                     will(returnValue(plate));
+                    one(sampleRelationshipDAO).listSampleParents(List.of(plate.getId()));
+                    will(returnValue(List.of()));
 
                     one(screeningBOFactory).createSampleLister(session);
                     will(returnValue(sampleLister));