From 0e13015b699cdb38c6f5db5a782cc4d81f595871 Mon Sep 17 00:00:00 2001
From: uhensler <none@none>
Date: Mon, 4 Jun 2018 13:47:50 +0200
Subject: [PATCH] OO-3303: Refactoring to improve performance of report
 printing

---
 .../modules/forms/EvaluationFormManager.java  |  5 +-
 .../manager/EvaluationFormManagerImpl.java    | 11 +--
 .../manager/EvaluationFormResponseDAO.java    | 68 +++------------
 .../manager/EvaluationFormSessionDAO.java     | 42 ---------
 .../model/jpa/EvaluationFormResponses.java    | 86 +++++++++++++++++++
 .../forms/ui/DisclaimerController.java        |  6 +-
 .../ui/EvaluationFormExecutionController.java | 37 +++++---
 .../ui/EvaluationFormPrintController.java     | 22 ++---
 ...valuationFormPrintSelectionController.java |  6 +-
 ...valuationFormReportSegmentsController.java |  6 +-
 .../ui/EvaluationFormReportsController.java   |  6 +-
 ...luationFormSessionSelectionController.java |  5 +-
 .../forms/ui/FileUploadController.java        |  6 +-
 .../forms/ui/MultipleChoiceController.java    | 18 ++--
 .../modules/forms/ui/RubricController.java    | 28 +++---
 ...SessionInformationLegendNameGenerator.java | 21 ++---
 .../ui/SessionInformationsController.java     | 13 +--
 .../forms/ui/SingleChoiceController.java      |  6 +-
 .../modules/forms/ui/TextInputController.java |  6 +-
 .../model/EvaluationFormComponentElement.java |  4 +-
 .../model/EvaluationFormExecutionElement.java |  4 +-
 .../EvaluationFormResponseController.java     |  4 +-
 ...aluationFormResponseControllerElement.java |  6 +-
 .../EvaluationFormResponseDAOTest.java        | 26 +++++-
 24 files changed, 232 insertions(+), 210 deletions(-)
 create mode 100644 src/main/java/org/olat/modules/forms/model/jpa/EvaluationFormResponses.java

diff --git a/src/main/java/org/olat/modules/forms/EvaluationFormManager.java b/src/main/java/org/olat/modules/forms/EvaluationFormManager.java
index 416902d8bfe..d54871ee311 100644
--- a/src/main/java/org/olat/modules/forms/EvaluationFormManager.java
+++ b/src/main/java/org/olat/modules/forms/EvaluationFormManager.java
@@ -29,6 +29,7 @@ import org.olat.core.commons.persistence.SortKey;
 import org.olat.core.id.Identity;
 import org.olat.core.id.OLATResourceable;
 import org.olat.core.util.vfs.VFSLeaf;
+import org.olat.modules.forms.model.jpa.EvaluationFormResponses;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryEntryRef;
 
@@ -153,9 +154,7 @@ public interface EvaluationFormManager {
 
 	public EvaluationFormResponse updateNoResponse(EvaluationFormResponse response);
 
-	public EvaluationFormResponse loadResponse(String responseIdentifier, EvaluationFormSessionRef session);
-
-	public List<EvaluationFormResponse> loadResponses(String responseIdentifier, EvaluationFormSessionRef session);
+	public EvaluationFormResponses loadResponsesBySessions(List<? extends EvaluationFormSessionRef> sessionRefs);
 
 	public File loadResponseFile(EvaluationFormResponse response);
 
diff --git a/src/main/java/org/olat/modules/forms/manager/EvaluationFormManagerImpl.java b/src/main/java/org/olat/modules/forms/manager/EvaluationFormManagerImpl.java
index f961bd3d4c5..d7e786dfb55 100644
--- a/src/main/java/org/olat/modules/forms/manager/EvaluationFormManagerImpl.java
+++ b/src/main/java/org/olat/modules/forms/manager/EvaluationFormManagerImpl.java
@@ -43,6 +43,7 @@ import org.olat.modules.forms.EvaluationFormSessionRef;
 import org.olat.modules.forms.EvaluationFormSessionStatus;
 import org.olat.modules.forms.EvaluationFormStatistic;
 import org.olat.modules.forms.EvaluationFormSurvey;
+import org.olat.modules.forms.model.jpa.EvaluationFormResponses;
 import org.olat.repository.RepositoryEntry;
 import org.olat.repository.RepositoryEntryRef;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -268,13 +269,9 @@ public class EvaluationFormManagerImpl implements EvaluationFormManager {
 	}
 
 	@Override
-	public EvaluationFormResponse loadResponse(String responseIdentifier, EvaluationFormSessionRef session) {
-		return evaluationFormResponseDao.loadResponse(responseIdentifier, session);
-	}
-
-	@Override
-	public List<EvaluationFormResponse> loadResponses(String responseIdentifier, EvaluationFormSessionRef session) {
-		return evaluationFormResponseDao.loadResponses(responseIdentifier, session);
+	public EvaluationFormResponses loadResponsesBySessions(List<? extends EvaluationFormSessionRef> sessionRefs) {
+		List<EvaluationFormResponse> responses = evaluationFormResponseDao.loadResponsesBySessions(sessionRefs);
+		return new EvaluationFormResponses(responses);
 	}
 
 	@Override
diff --git a/src/main/java/org/olat/modules/forms/manager/EvaluationFormResponseDAO.java b/src/main/java/org/olat/modules/forms/manager/EvaluationFormResponseDAO.java
index c4bf58f00e9..0bdf2883c85 100644
--- a/src/main/java/org/olat/modules/forms/manager/EvaluationFormResponseDAO.java
+++ b/src/main/java/org/olat/modules/forms/manager/EvaluationFormResponseDAO.java
@@ -22,22 +22,16 @@ package org.olat.modules.forms.manager;
 import java.math.BigDecimal;
 import java.nio.file.Path;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Date;
 import java.util.List;
 import java.util.stream.Collectors;
 
-import javax.persistence.TypedQuery;
-
-import org.olat.basesecurity.IdentityRef;
 import org.olat.core.commons.persistence.DB;
 import org.olat.modules.forms.EvaluationFormResponse;
 import org.olat.modules.forms.EvaluationFormSession;
 import org.olat.modules.forms.EvaluationFormSessionRef;
-import org.olat.modules.forms.EvaluationFormSessionStatus;
 import org.olat.modules.forms.EvaluationFormSurvey;
 import org.olat.modules.forms.model.jpa.EvaluationFormResponseImpl;
-import org.olat.modules.portfolio.PageBody;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -80,39 +74,6 @@ public class EvaluationFormResponseDAO {
 		return response;
 	}
 
-	public List<EvaluationFormResponse> getResponsesFromPortfolioEvaluation(IdentityRef identity, PageBody anchor) {
-		StringBuilder sb = new StringBuilder();
-		sb.append("select response from evaluationformresponse as response")
-		  .append(" inner join response.session as session")
-		  .append(" where session.identity.key=:identityKey and session.pageBody.key=:bodyKey");
-		return dbInstance.getCurrentEntityManager()
-				.createQuery(sb.toString(), EvaluationFormResponse.class)
-				.setParameter("identityKey", identity.getKey())
-				.setParameter("bodyKey", anchor.getKey())
-				.getResultList();
-	}
-	
-	public List<EvaluationFormResponse> getResponsesFromPortfolioEvaluation(List<? extends IdentityRef> identities, PageBody anchor, EvaluationFormSessionStatus status) {
-		if(identities == null || identities.isEmpty()) return Collections.emptyList();
-		
-		List<Long> identitiyKeys = identities.stream().map(i -> i.getKey()).collect(Collectors.toList());
-		StringBuilder sb = new StringBuilder();
-		sb.append("select response from evaluationformresponse as response")
-		  .append(" inner join response.session as session")
-		  .append(" where session.identity.key in (:identityKeys) and session.pageBody.key=:bodyKey");
-		if(status != null) {
-			sb.append(" and session.status=:status");
-		}
-		TypedQuery<EvaluationFormResponse> rQuery = dbInstance.getCurrentEntityManager()
-				.createQuery(sb.toString(), EvaluationFormResponse.class)
-				.setParameter("identityKeys", identitiyKeys)
-				.setParameter("bodyKey", anchor.getKey());
-		if(status != null) {
-			rQuery.setParameter("status", status.name());
-		}
-		return rQuery.getResultList();
-	}
-	
 	public EvaluationFormResponse updateResponse(BigDecimal numericalValue, String stringuifiedResponse,
 			Path fileResponse, EvaluationFormResponse response) {
 		EvaluationFormResponseImpl evalResponse = (EvaluationFormResponseImpl)response;
@@ -144,22 +105,16 @@ public class EvaluationFormResponseDAO {
 				.executeUpdate();
 	}
 
-	public EvaluationFormResponse loadResponse(String responseIdentifier, EvaluationFormSessionRef session) {
-		List<EvaluationFormResponse> resultList = loadResponses(responseIdentifier, session);
-		return resultList.isEmpty()? null: resultList.get(0);
-	}
-
-	public List<EvaluationFormResponse> loadResponses(String responseIdentifier, EvaluationFormSessionRef session) {
-		String query = new StringBuilder()
-				.append("select response from evaluationformresponse as response")
-				.append(" inner join response.session as session")
-				.append(" where session.key=:sessionKey and response.responseIdentifier=:responseIdentifier")
-				.toString();
+	public List<EvaluationFormResponse> loadResponsesBySessions(List<? extends EvaluationFormSessionRef> sessionRefs) {
+		StringBuilder sb = new StringBuilder();
+		sb.append("select response from evaluationformresponse as response");
+		sb.append(" inner join fetch response.session as session");
+		sb.append("  left outer join fetch session.participation as participation");
+		sb.append(" where session.key in (:sessionKeys)");
 		
 		return dbInstance.getCurrentEntityManager()
-				.createQuery(query, EvaluationFormResponse.class)
-				.setParameter("sessionKey", session.getKey())
-				.setParameter("responseIdentifier", responseIdentifier)
+				.createQuery(sb.toString(), EvaluationFormResponse.class)
+				.setParameter("sessionKeys", getSessionKeys(sessionRefs))
 				.getResultList();
 	}
 
@@ -168,7 +123,8 @@ public class EvaluationFormResponseDAO {
 		
 		StringBuilder sb = new StringBuilder();
 		sb.append("select response from evaluationformresponse as response");
-		sb.append(" inner join response.session as session");
+		sb.append(" inner join fetch response.session as session");
+		sb.append("  left outer join fetch session.participation as participation");
 		sb.append(" inner join session.survey as survey");
 		sb.append(" where survey.key=:surveyKey");
 		
@@ -177,5 +133,9 @@ public class EvaluationFormResponseDAO {
 				.setParameter("surveyKey", survey.getKey())
 				.getResultList();
 	}
+	
+	private List<Long> getSessionKeys(List<? extends EvaluationFormSessionRef> sessionRefs) {
+		return sessionRefs.stream().map(EvaluationFormSessionRef::getKey).collect(Collectors.toList());
+	}
 
 }
diff --git a/src/main/java/org/olat/modules/forms/manager/EvaluationFormSessionDAO.java b/src/main/java/org/olat/modules/forms/manager/EvaluationFormSessionDAO.java
index 0efa49637be..458dfe669e6 100644
--- a/src/main/java/org/olat/modules/forms/manager/EvaluationFormSessionDAO.java
+++ b/src/main/java/org/olat/modules/forms/manager/EvaluationFormSessionDAO.java
@@ -107,48 +107,6 @@ class EvaluationFormSessionDAO {
 			sb.append(" order by ");
 			sb.append(sortKey);
 			appendAsc(sb, asc);
-//			switch(sortKey) {
-//				case "itemType":
-//					sb.append(itemDbRef).append(".type.type ");
-//					appendAsc(sb, asc);
-//					break;
-//				case "marks":
-//					sb.append("marks");
-//					appendAsc(sb, asc);
-//					break;
-//				case "rating":
-//					sb.append("rating");
-//					appendAsc(sb, asc);
-//					sb.append(" nulls last");
-//					break;
-//				case "numberOfRatings":
-//					sb.append("numberOfRatingsTotal");
-//					appendAsc(sb, asc);
-//					sb.append(" nulls last");
-//					break;
-//				case "keywords":
-//				case "coverage":
-//				case "additionalInformations":
-//					sb.append("lower(").append(itemDbRef).append(".").append(sortKey).append(")");
-//					appendAsc(sb, asc);
-//					sb.append(" nulls last");
-//					break;
-//				case "taxonomyLevel":
-//					sb.append("lower(").append(taxonomyDbRef).append(".displayName)");
-//					appendAsc(sb, asc);
-//					sb.append(" nulls last");
-//					break;
-//				case "taxonomyPath":
-//					sb.append("lower(").append(taxonomyDbRef).append(".materializedPathIdentifiers)");
-//					appendAsc(sb, asc);
-//					sb.append(" nulls last");
-//					break;
-//				default:
-//					sb.append(itemDbRef).append(".").append(sortKey);
-//					appendAsc(sb, asc);
-//					sb.append(" nulls last");
-//					break;
-//			}
 		} else {
 			sb.append(" order by session.key asc ");
 		}
diff --git a/src/main/java/org/olat/modules/forms/model/jpa/EvaluationFormResponses.java b/src/main/java/org/olat/modules/forms/model/jpa/EvaluationFormResponses.java
new file mode 100644
index 00000000000..d6631f909b5
--- /dev/null
+++ b/src/main/java/org/olat/modules/forms/model/jpa/EvaluationFormResponses.java
@@ -0,0 +1,86 @@
+/**
+ * <a href="http://www.openolat.org">
+ * OpenOLAT - Online Learning and Training</a><br>
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); <br>
+ * you may not use this file except in compliance with the License.<br>
+ * You may obtain a copy of the License at the
+ * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a>
+ * <p>
+ * Unless required by applicable law or agreed to in writing,<br>
+ * software distributed under the License is distributed on an "AS IS" BASIS, <br>
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br>
+ * See the License for the specific language governing permissions and <br>
+ * limitations under the License.
+ * <p>
+ * Initial code contributed and copyrighted by<br>
+ * frentix GmbH, http://www.frentix.com
+ * <p>
+ */
+package org.olat.modules.forms.model.jpa;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.olat.modules.forms.EvaluationFormResponse;
+import org.olat.modules.forms.EvaluationFormSession;
+
+/**
+ * 
+ * Initial date: 04.06.2018<br>
+ * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com
+ *
+ */
+public class EvaluationFormResponses {
+	
+	private final Map<EvaluationFormSession, Map<String, List<EvaluationFormResponse>>> sesssionToResponses;
+
+	public EvaluationFormResponses(List<EvaluationFormResponse> responses) {
+		sesssionToResponses = new HashMap<>();
+		for (EvaluationFormResponse response: responses) {
+			EvaluationFormSession session = response.getSession();
+			String identifier = response.getResponseIdentifier();
+
+			Map<String, List<EvaluationFormResponse>> identifierToResponse = sesssionToResponses.get(session);
+			if (identifierToResponse == null) {
+				identifierToResponse = new HashMap<>();
+				sesssionToResponses.put(session, identifierToResponse);
+			}
+			
+			List<EvaluationFormResponse> responseList = identifierToResponse.get(identifier);
+			if (responseList == null) {
+				responseList = new ArrayList<>();
+				identifierToResponse.put(identifier, responseList);
+			}
+			responseList.add(response);
+		}
+	}
+
+	public EvaluationFormResponse getResponse(EvaluationFormSession session, String responseIdentifier) {
+		List<EvaluationFormResponse> responses = getResponses(session, responseIdentifier);
+		if (!responses.isEmpty()) {
+			return responses.get(0);
+		}
+		return null;
+	}
+
+	public List<EvaluationFormResponse> getResponses(EvaluationFormSession session, String responseIdentitfier) {
+		Map<String, List<EvaluationFormResponse>> identifierToResponses = getResponsesBySession(session);
+		List<EvaluationFormResponse> responses = identifierToResponses.get(responseIdentitfier);
+		if (responses == null) {
+			responses = new ArrayList<>(0);
+		}
+		return responses;
+	}
+
+	private Map<String, List<EvaluationFormResponse>> getResponsesBySession(EvaluationFormSession session) {
+		Map<String, List<EvaluationFormResponse>> identifierToResponses = sesssionToResponses.get(session);
+		if (identifierToResponses == null) {
+			identifierToResponses = new HashMap<>(0);
+		}
+		return identifierToResponses;
+	}
+
+}
diff --git a/src/main/java/org/olat/modules/forms/ui/DisclaimerController.java b/src/main/java/org/olat/modules/forms/ui/DisclaimerController.java
index a955b66125c..8722ec126e3 100644
--- a/src/main/java/org/olat/modules/forms/ui/DisclaimerController.java
+++ b/src/main/java/org/olat/modules/forms/ui/DisclaimerController.java
@@ -32,7 +32,7 @@ import org.olat.core.util.StringHelper;
 import org.olat.modules.forms.EvaluationFormManager;
 import org.olat.modules.forms.EvaluationFormResponse;
 import org.olat.modules.forms.EvaluationFormSession;
-import org.olat.modules.forms.EvaluationFormSessionRef;
+import org.olat.modules.forms.model.jpa.EvaluationFormResponses;
 import org.olat.modules.forms.model.xml.Disclaimer;
 import org.olat.modules.forms.ui.model.EvaluationFormResponseController;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -124,8 +124,8 @@ public class DisclaimerController extends FormBasicController implements Evaluat
 	}
 
 	@Override
-	public void loadResponse(EvaluationFormSessionRef session) {
-		response = evaluationFormManager.loadResponse(disclaimer.getId(), session);
+	public void initResponse(EvaluationFormSession session, EvaluationFormResponses responses) {
+		response = responses.getResponse(session, disclaimer.getId());
 		boolean accepted = response != null && ACCEPTED_DB_KEY.equals(response.getStringuifiedResponse());
 		agreementEl.select(ACCEPTED_KEY, accepted);
 	}
diff --git a/src/main/java/org/olat/modules/forms/ui/EvaluationFormExecutionController.java b/src/main/java/org/olat/modules/forms/ui/EvaluationFormExecutionController.java
index f166720cbb4..463f45fb260 100644
--- a/src/main/java/org/olat/modules/forms/ui/EvaluationFormExecutionController.java
+++ b/src/main/java/org/olat/modules/forms/ui/EvaluationFormExecutionController.java
@@ -23,6 +23,7 @@ import static org.olat.modules.forms.handler.EvaluationFormResource.FORM_XML_FIL
 
 import java.io.File;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -48,10 +49,10 @@ import org.olat.core.util.xml.XStreamHelper;
 import org.olat.fileresource.FileResourceManager;
 import org.olat.modules.forms.EvaluationFormManager;
 import org.olat.modules.forms.EvaluationFormSession;
-import org.olat.modules.forms.EvaluationFormSessionRef;
 import org.olat.modules.forms.EvaluationFormSessionStatus;
 import org.olat.modules.forms.handler.AllHandlerPageProvider;
 import org.olat.modules.forms.handler.EvaluationFormElementHandler;
+import org.olat.modules.forms.model.jpa.EvaluationFormResponses;
 import org.olat.modules.forms.model.xml.AbstractElement;
 import org.olat.modules.forms.model.xml.Form;
 import org.olat.modules.forms.model.xml.FormXStream;
@@ -85,6 +86,7 @@ public class EvaluationFormExecutionController extends FormBasicController imple
 	private boolean immediateSave = false;
 	
 	private EvaluationFormSession session;
+	private final EvaluationFormResponses responses;
 	
 	@Autowired
 	private DB dbInstance;
@@ -92,26 +94,32 @@ public class EvaluationFormExecutionController extends FormBasicController imple
 	private EvaluationFormManager evaluationFormManager;
 	
 	public EvaluationFormExecutionController(UserRequest ureq, WindowControl wControl, EvaluationFormSession session) {
-		this(ureq, wControl, null, session, false, true);
+		this(ureq, wControl, null, session, null, false, true);
 	}
 	
 	/**
-	 * Optimized to avoid the loading of the form from the XML file.
+	 * Optimized to use already loaded responses and form.
 	 * 
 	 */
-	public EvaluationFormExecutionController(UserRequest ureq, WindowControl wControl, EvaluationFormSession session, Form form) {
-		this(ureq, wControl, form, session, false, true);
+	public EvaluationFormExecutionController(UserRequest ureq, WindowControl wControl, EvaluationFormSession session,
+			EvaluationFormResponses responses, Form form) {
+		this(ureq, wControl, form, session, responses, false, true);
 	}
 	
 	public EvaluationFormExecutionController(UserRequest ureq, WindowControl wControl, EvaluationFormSession session,
 			boolean readOnly, boolean showDoneButton) {
-		this(ureq, wControl, null, session, readOnly, showDoneButton);
+		this(ureq, wControl, null, session, null, readOnly, showDoneButton);
 	}
 	
 	private EvaluationFormExecutionController(UserRequest ureq, WindowControl wControl, Form form,
-			EvaluationFormSession session, boolean readOnly, boolean showDoneButton) {
+			EvaluationFormSession session, EvaluationFormResponses responses, boolean readOnly,
+			boolean showDoneButton) {
 		super(ureq, wControl, "execute");
 		
+		this.session = session;
+		this.readOnly = readOnly;
+		this.showDoneButton = showDoneButton;
+		
 		if (form != null) {
 			this.form = form;
 		} else {
@@ -123,9 +131,11 @@ public class EvaluationFormExecutionController extends FormBasicController imple
 			this.form = (Form)XStreamHelper.readObject(FormXStream.getXStream(), formFile);
 		}
 		
-		this.session = session;
-		this.readOnly = readOnly;
-		this.showDoneButton = showDoneButton;
+		if (responses != null) {
+			this.responses = responses;
+		} else {
+			this.responses = evaluationFormManager.loadResponsesBySessions(Collections.singletonList(session));
+		}
 		
 		initForm(ureq);
 	}
@@ -136,6 +146,7 @@ public class EvaluationFormExecutionController extends FormBasicController imple
 		this.form = (Form)XStreamHelper.readObject(FormXStream.getXStream(), formFile);
 		
 		this.session = null;
+		this.responses = null;
 		this.readOnly = false;
 		this.showDoneButton = false;
 		
@@ -205,7 +216,7 @@ public class EvaluationFormExecutionController extends FormBasicController imple
 		if (session == null) return;
 		
 		for (ExecutionFragment fragment: fragments) {
-			fragment.load(session);
+			fragment.initResponse(session, responses);
 		}
 	}
 	
@@ -351,8 +362,8 @@ public class EvaluationFormExecutionController extends FormBasicController imple
 			return executionElement.hasResponse();
 		}
 		
-		public void load(EvaluationFormSessionRef session) {
-			executionElement.loadResponse(session);
+		public void initResponse(EvaluationFormSession session, EvaluationFormResponses responses){
+			executionElement.initResponse(session, responses);;
 		}
 		
 		public void save(EvaluationFormSession session) {
diff --git a/src/main/java/org/olat/modules/forms/ui/EvaluationFormPrintController.java b/src/main/java/org/olat/modules/forms/ui/EvaluationFormPrintController.java
index 730cfe2ac90..9660f80f2b0 100644
--- a/src/main/java/org/olat/modules/forms/ui/EvaluationFormPrintController.java
+++ b/src/main/java/org/olat/modules/forms/ui/EvaluationFormPrintController.java
@@ -33,11 +33,11 @@ import org.olat.core.util.CodeHelper;
 import org.olat.modules.forms.EvaluationFormManager;
 import org.olat.modules.forms.EvaluationFormPrintSelection;
 import org.olat.modules.forms.EvaluationFormSession;
-import org.olat.modules.forms.EvaluationFormSessionRef;
 import org.olat.modules.forms.handler.DefaultReportProvider;
 import org.olat.modules.forms.handler.MultipleChoiceTableHandler;
 import org.olat.modules.forms.handler.RubricTableHandler;
 import org.olat.modules.forms.handler.SingleChoiceTableHandler;
+import org.olat.modules.forms.model.jpa.EvaluationFormResponses;
 import org.olat.modules.forms.model.xml.Form;
 import org.olat.modules.forms.model.xml.MultipleChoice;
 import org.olat.modules.forms.model.xml.Rubric;
@@ -56,14 +56,14 @@ public class EvaluationFormPrintController extends BasicController {
 	private VelocityContainer mainVC;
 	
 	private final Form form;
-	private final List<? extends EvaluationFormSessionRef> sessions;
+	private final List<EvaluationFormSession> sessions;
 	private final ReportHelper reportHelper;
 	
 	@Autowired
 	private EvaluationFormManager evaluationFormManager;
 
 	public EvaluationFormPrintController(UserRequest ureq, WindowControl wControl, Form form,
-			List<? extends EvaluationFormSessionRef> sessions, ReportHelper reportHelper,
+			List<EvaluationFormSession> sessions, ReportHelper reportHelper,
 			EvaluationFormPrintSelection printSelection) {
 		super(ureq, wControl);
 		this.form = form;
@@ -101,19 +101,21 @@ public class EvaluationFormPrintController extends BasicController {
 
 	private List<SessionWrapper> createSessionWrappers(UserRequest ureq) {
 		List<SessionWrapper> wrappers = new ArrayList<>();
-		for (EvaluationFormSessionRef sessionRef: sessions) {
-			SessionWrapper wrapper = createSessionWrapper(ureq, sessionRef);
+		List<EvaluationFormSession> reloadedSessions = evaluationFormManager.loadSessionsByKey(sessions, 0, -1);
+		EvaluationFormResponses responses = evaluationFormManager.loadResponsesBySessions(sessions);
+		for (EvaluationFormSession session: reloadedSessions) {
+			SessionWrapper wrapper = createSessionWrapper(ureq, session, responses);
 			wrappers.add(wrapper);
 		}
 		return wrappers;
 	}
 	
-	private SessionWrapper createSessionWrapper(UserRequest ureq, EvaluationFormSessionRef sessionRef) {
-		EvaluationFormSession reloadedSession = evaluationFormManager.loadSessionByKey(sessionRef);
+	private SessionWrapper createSessionWrapper(UserRequest ureq, EvaluationFormSession session,
+			EvaluationFormResponses responses) {
 		String componentName = "se_" + CodeHelper.getRAMUniqueID();
-		String legendName = reportHelper.getLegend(reloadedSession).getName();
-		Controller controller = new EvaluationFormExecutionController(ureq, getWindowControl(), reloadedSession,
-				form);
+		String legendName = reportHelper.getLegend(session).getName();
+		Controller controller = new EvaluationFormExecutionController(ureq, getWindowControl(), session,
+				responses, form);
 		mainVC.put(componentName, controller.getInitialComponent());
 		return new SessionWrapper(legendName, componentName);
 	}
diff --git a/src/main/java/org/olat/modules/forms/ui/EvaluationFormPrintSelectionController.java b/src/main/java/org/olat/modules/forms/ui/EvaluationFormPrintSelectionController.java
index 7801ee8983b..2f87f79e5cd 100644
--- a/src/main/java/org/olat/modules/forms/ui/EvaluationFormPrintSelectionController.java
+++ b/src/main/java/org/olat/modules/forms/ui/EvaluationFormPrintSelectionController.java
@@ -40,7 +40,7 @@ import org.olat.core.gui.control.Event;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.control.creator.ControllerCreator;
 import org.olat.modules.forms.EvaluationFormPrintSelection;
-import org.olat.modules.forms.EvaluationFormSessionRef;
+import org.olat.modules.forms.EvaluationFormSession;
 import org.olat.modules.forms.model.xml.Form;
 
 /**
@@ -66,12 +66,12 @@ public class EvaluationFormPrintSelectionController extends FormBasicController
 	private Link printLink;
 
 	private final Form form;
-	private final List<? extends EvaluationFormSessionRef> sessions;
+	private final List<EvaluationFormSession> sessions;
 	private final ReportHelper reportHelper;
 	private final EvaluationFormPrintSelection printSelection;
 
 	public EvaluationFormPrintSelectionController(UserRequest ureq, WindowControl wControl, Form form,
-			List<? extends EvaluationFormSessionRef> sessions, ReportHelper reportHelper) {
+			List<EvaluationFormSession> sessions, ReportHelper reportHelper) {
 		super(ureq, wControl, "report_print_selection");
 		this.form = form;
 		this.sessions = sessions;
diff --git a/src/main/java/org/olat/modules/forms/ui/EvaluationFormReportSegmentsController.java b/src/main/java/org/olat/modules/forms/ui/EvaluationFormReportSegmentsController.java
index e7f21c13106..565bdd0a03e 100644
--- a/src/main/java/org/olat/modules/forms/ui/EvaluationFormReportSegmentsController.java
+++ b/src/main/java/org/olat/modules/forms/ui/EvaluationFormReportSegmentsController.java
@@ -33,7 +33,7 @@ import org.olat.core.gui.components.velocity.VelocityContainer;
 import org.olat.core.gui.control.Event;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.control.controller.BasicController;
-import org.olat.modules.forms.EvaluationFormSessionRef;
+import org.olat.modules.forms.EvaluationFormSession;
 import org.olat.modules.forms.handler.DefaultReportProvider;
 import org.olat.modules.forms.handler.MultipleChoiceTableHandler;
 import org.olat.modules.forms.handler.RubricTableHandler;
@@ -68,11 +68,11 @@ public class EvaluationFormReportSegmentsController extends BasicController {
 	private EvaluationFormSessionSelectionController sessionSelectionCtrl;
 	
 	private final Form form;
-	private final List<? extends EvaluationFormSessionRef> sessions;
+	private final List<EvaluationFormSession> sessions;
 	private final ReportHelper reportHelper;
 	
 	public EvaluationFormReportSegmentsController(UserRequest ureq, WindowControl wControl, Form form,
-			List<? extends EvaluationFormSessionRef> sessions, ReportHelper reportHelper) {
+			List<EvaluationFormSession> sessions, ReportHelper reportHelper) {
 		super(ureq, wControl);
 		this.form = form;
 		this.sessions = sessions;
diff --git a/src/main/java/org/olat/modules/forms/ui/EvaluationFormReportsController.java b/src/main/java/org/olat/modules/forms/ui/EvaluationFormReportsController.java
index d6788745225..d06292acf42 100644
--- a/src/main/java/org/olat/modules/forms/ui/EvaluationFormReportsController.java
+++ b/src/main/java/org/olat/modules/forms/ui/EvaluationFormReportsController.java
@@ -31,7 +31,7 @@ import org.olat.core.gui.control.Event;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.control.controller.BasicController;
 import org.olat.core.gui.control.generic.closablewrapper.CloseableCalloutWindowController;
-import org.olat.modules.forms.EvaluationFormSessionRef;
+import org.olat.modules.forms.EvaluationFormSession;
 import org.olat.modules.forms.model.xml.Form;
 
 /**
@@ -49,11 +49,11 @@ public class EvaluationFormReportsController extends BasicController {
 	private EvaluationFormPrintSelectionController printSelectionCtrl;
 	
 	private final Form form;
-	private final List<? extends EvaluationFormSessionRef> sessions;
+	private final List<EvaluationFormSession> sessions;
 	private final ReportHelper reportHelper;
 
 	public EvaluationFormReportsController(UserRequest ureq, WindowControl wControl, Form form,
-			List<? extends EvaluationFormSessionRef> sessions) {
+			List<EvaluationFormSession> sessions) {
 		super(ureq, wControl);
 		this.form = form;
 		this.sessions = sessions;
diff --git a/src/main/java/org/olat/modules/forms/ui/EvaluationFormSessionSelectionController.java b/src/main/java/org/olat/modules/forms/ui/EvaluationFormSessionSelectionController.java
index 4d6068a7dc0..5fd883760ec 100644
--- a/src/main/java/org/olat/modules/forms/ui/EvaluationFormSessionSelectionController.java
+++ b/src/main/java/org/olat/modules/forms/ui/EvaluationFormSessionSelectionController.java
@@ -19,6 +19,7 @@
  */
 package org.olat.modules.forms.ui;
 
+import java.util.Collections;
 import java.util.List;
 
 import org.olat.core.gui.UserRequest;
@@ -38,6 +39,7 @@ import org.olat.core.gui.control.WindowControl;
 import org.olat.modules.forms.EvaluationFormManager;
 import org.olat.modules.forms.EvaluationFormSession;
 import org.olat.modules.forms.EvaluationFormSessionRef;
+import org.olat.modules.forms.model.jpa.EvaluationFormResponses;
 import org.olat.modules.forms.model.xml.Form;
 import org.olat.modules.forms.model.xml.SessionInformations.InformationType;
 import org.olat.modules.forms.ui.SessionSelectionModel.SessionSelectionCols;
@@ -142,9 +144,10 @@ public class EvaluationFormSessionSelectionController extends FormBasicControlle
 
 	private void doShowQuickview(UserRequest ureq, SessionSelectionRow row) {
 		EvaluationFormSession reloadedSession = evaluationFormManager.loadSessionByKey(row.getSession());
+		EvaluationFormResponses responses = evaluationFormManager.loadResponsesBySessions(Collections.singletonList(reloadedSession));
 		String legendName = reportHelper.getLegend(reloadedSession).getName();
 		EvaluationFormExecutionController controller = new EvaluationFormExecutionController(ureq, getWindowControl(),
-				reloadedSession, form);
+				reloadedSession, responses, form);
 		stackPanel.pushController(legendName, controller);
 	}
 
diff --git a/src/main/java/org/olat/modules/forms/ui/FileUploadController.java b/src/main/java/org/olat/modules/forms/ui/FileUploadController.java
index 4934a04df17..46a4219c6c6 100644
--- a/src/main/java/org/olat/modules/forms/ui/FileUploadController.java
+++ b/src/main/java/org/olat/modules/forms/ui/FileUploadController.java
@@ -39,7 +39,7 @@ import org.olat.core.util.CodeHelper;
 import org.olat.modules.forms.EvaluationFormManager;
 import org.olat.modules.forms.EvaluationFormResponse;
 import org.olat.modules.forms.EvaluationFormSession;
-import org.olat.modules.forms.EvaluationFormSessionRef;
+import org.olat.modules.forms.model.jpa.EvaluationFormResponses;
 import org.olat.modules.forms.model.xml.FileUpload;
 import org.olat.modules.forms.ui.model.EvaluationFormResponseController;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -136,8 +136,8 @@ public class FileUploadController extends FormBasicController implements Evaluat
 	}
 
 	@Override
-	public void loadResponse(EvaluationFormSessionRef session) {
-		response = evaluationFormManager.loadResponse(fileUpload.getId(), session);
+	public void initResponse(EvaluationFormSession session, EvaluationFormResponses responses) {
+		response = responses.getResponse(session, fileUpload.getId());
 		File responseFile = evaluationFormManager.loadResponseFile(response);
 		if (responseFile != null) {
 			fileEl.setInitialFile(responseFile);
diff --git a/src/main/java/org/olat/modules/forms/ui/MultipleChoiceController.java b/src/main/java/org/olat/modules/forms/ui/MultipleChoiceController.java
index b61571124fe..4578d37ad73 100644
--- a/src/main/java/org/olat/modules/forms/ui/MultipleChoiceController.java
+++ b/src/main/java/org/olat/modules/forms/ui/MultipleChoiceController.java
@@ -38,7 +38,7 @@ import org.olat.core.util.StringHelper;
 import org.olat.modules.forms.EvaluationFormManager;
 import org.olat.modules.forms.EvaluationFormResponse;
 import org.olat.modules.forms.EvaluationFormSession;
-import org.olat.modules.forms.EvaluationFormSessionRef;
+import org.olat.modules.forms.model.jpa.EvaluationFormResponses;
 import org.olat.modules.forms.model.xml.Choice;
 import org.olat.modules.forms.model.xml.MultipleChoice;
 import org.olat.modules.forms.ui.model.EvaluationFormResponseController;
@@ -58,7 +58,7 @@ public class MultipleChoiceController extends FormBasicController implements Eva
 	private TextElement otherEl;
 	
 	private final MultipleChoice multipleChoice;
-	private List<EvaluationFormResponse> responses;
+	private List<EvaluationFormResponse> multipleChoiceResponses;
 	
 	@Autowired
 	private EvaluationFormManager evaluationFormManager;
@@ -140,13 +140,13 @@ public class MultipleChoiceController extends FormBasicController implements Eva
 
 	@Override
 	public boolean hasResponse() {
-		return !responses.isEmpty();
+		return !multipleChoiceResponses.isEmpty();
 	}
 
 	@Override
-	public void loadResponse(EvaluationFormSessionRef session) {
-		responses = evaluationFormManager.loadResponses(multipleChoice.getId(), session);
-		for (EvaluationFormResponse response : responses) {
+	public void initResponse(EvaluationFormSession session, EvaluationFormResponses responses) {
+		multipleChoiceResponses = responses.getResponses(session, multipleChoice.getId());
+		for (EvaluationFormResponse response: multipleChoiceResponses) {
 			String key = response.getStringuifiedResponse();
 			if (multipleChoiceEl.getKeys().contains(key)) {
 				multipleChoiceEl.select(key, true);
@@ -160,14 +160,14 @@ public class MultipleChoiceController extends FormBasicController implements Eva
 
 	@Override
 	public void saveResponse(EvaluationFormSession session) {
-		evaluationFormManager.deleteResponses(responses);
+		evaluationFormManager.deleteResponses(multipleChoiceResponses);
 
 		Collection<String> selectedChoises = new ArrayList<>(multipleChoiceEl.getSelectedKeys());
 		replaceOthersKeyWithValue(selectedChoises);
-		responses = new ArrayList<>();
+		multipleChoiceResponses = new ArrayList<>();
 		for (String choice: selectedChoises) {
 			EvaluationFormResponse response = evaluationFormManager.createStringResponse(multipleChoice.getId(), session, choice);
-			responses.add(response);
+			multipleChoiceResponses.add(response);
 		}
 	}
 
diff --git a/src/main/java/org/olat/modules/forms/ui/RubricController.java b/src/main/java/org/olat/modules/forms/ui/RubricController.java
index aa2861e0f8d..60dde66a7df 100644
--- a/src/main/java/org/olat/modules/forms/ui/RubricController.java
+++ b/src/main/java/org/olat/modules/forms/ui/RubricController.java
@@ -41,7 +41,7 @@ import org.olat.core.util.StringHelper;
 import org.olat.modules.forms.EvaluationFormManager;
 import org.olat.modules.forms.EvaluationFormResponse;
 import org.olat.modules.forms.EvaluationFormSession;
-import org.olat.modules.forms.EvaluationFormSessionRef;
+import org.olat.modules.forms.model.jpa.EvaluationFormResponses;
 import org.olat.modules.forms.model.xml.Rubric;
 import org.olat.modules.forms.model.xml.Rubric.SliderType;
 import org.olat.modules.forms.model.xml.Slider;
@@ -62,7 +62,7 @@ public class RubricController extends FormBasicController implements EvaluationF
 	
 	private final Rubric rubric;
 	private List<SliderWrapper> sliderWrappers;
-	private Map<String, EvaluationFormResponse> responses = new HashMap<>();
+	private Map<String, EvaluationFormResponse> rubricResponses = new HashMap<>();
 	
 	@Autowired
 	private EvaluationFormManager evaluationFormManager;
@@ -234,10 +234,10 @@ public class RubricController extends FormBasicController implements EvaluationF
 	@Override
 	public boolean hasResponse() {
 		for (SliderWrapper sliderWrapper: sliderWrappers) {
-			if (!responses.containsKey(sliderWrapper.getId())) {
+			if (!rubricResponses.containsKey(sliderWrapper.getId())) {
 				return false;
 			}
-			EvaluationFormResponse response = responses.get(sliderWrapper.getId());
+			EvaluationFormResponse response = rubricResponses.get(sliderWrapper.getId());
 			if (response == null || (!response.isNoResponse()) && response.getNumericalResponse() == null) {
 				return false;
 			}
@@ -246,11 +246,11 @@ public class RubricController extends FormBasicController implements EvaluationF
 	}
 
 	@Override
-	public void loadResponse(EvaluationFormSessionRef session) {
+	public void initResponse(EvaluationFormSession session, EvaluationFormResponses responses) {
 		for (SliderWrapper sliderWrapper: sliderWrappers) {
-			EvaluationFormResponse response = evaluationFormManager.loadResponse(sliderWrapper.getId(), session);
+			EvaluationFormResponse response = responses.getResponse(session, sliderWrapper.getId());
 			if (response != null) {
-				responses.put(sliderWrapper.getId(), response);
+				rubricResponses.put(sliderWrapper.getId(), response);
 				if (response.getNumericalResponse() != null) {
 					BigDecimal numericalResponse = response.getNumericalResponse();
 					setValue(sliderWrapper, numericalResponse);
@@ -261,7 +261,7 @@ public class RubricController extends FormBasicController implements EvaluationF
 	}
 
 	private void disableSliderIfNoResponse(SliderWrapper sliderWrapper) {
-		EvaluationFormResponse response = responses.get(sliderWrapper.getId());
+		EvaluationFormResponse response = rubricResponses.get(sliderWrapper.getId());
 		if (response != null && response.isNoResponse()) {
 			MultipleSelectionElement noResponseEl = sliderWrapper.getNoResponseEl();
 			if (noResponseEl != null) {
@@ -322,13 +322,13 @@ public class RubricController extends FormBasicController implements EvaluationF
 	}
 	
 	private void saveNoResponse(EvaluationFormSession session, SliderWrapper sliderWrapper) {
-		EvaluationFormResponse response = responses.get(sliderWrapper.getId());
+		EvaluationFormResponse response = rubricResponses.get(sliderWrapper.getId());
 		if (response == null) {
 			response = evaluationFormManager.createNoResponse(sliderWrapper.getId(), session);
 		} else {
 			response = evaluationFormManager.updateNoResponse(response);
 		}
-		responses.put(sliderWrapper.getId(), response);
+		rubricResponses.put(sliderWrapper.getId(), response);
 	}
 	
 	private void saveSliderResponse(EvaluationFormSession session, SliderWrapper sliderWrapper) {
@@ -346,18 +346,18 @@ public class RubricController extends FormBasicController implements EvaluationF
 			}
 		}
 		if (value != null) {
-			EvaluationFormResponse response = responses.get(sliderWrapper.getId());
+			EvaluationFormResponse response = rubricResponses.get(sliderWrapper.getId());
 			if (response == null) {
 				response = evaluationFormManager.createNumericalResponse(sliderWrapper.getId(), session, value);
 			} else {
 				response = evaluationFormManager.updateNumericalResponse(response, value);
 			}
-			responses.put(sliderWrapper.getId(), response);
+			rubricResponses.put(sliderWrapper.getId(), response);
 		} else {
-			EvaluationFormResponse response = responses.get(sliderWrapper.getId());
+			EvaluationFormResponse response = rubricResponses.get(sliderWrapper.getId());
 			if (response != null) {
 				evaluationFormManager.deleteResponse(response);
-				responses.remove(sliderWrapper.getId());
+				rubricResponses.remove(sliderWrapper.getId());
 			}
 		}
 	}
diff --git a/src/main/java/org/olat/modules/forms/ui/SessionInformationLegendNameGenerator.java b/src/main/java/org/olat/modules/forms/ui/SessionInformationLegendNameGenerator.java
index fe4ad00d215..5819114a161 100644
--- a/src/main/java/org/olat/modules/forms/ui/SessionInformationLegendNameGenerator.java
+++ b/src/main/java/org/olat/modules/forms/ui/SessionInformationLegendNameGenerator.java
@@ -23,13 +23,9 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.olat.core.CoreSpringFactory;
 import org.olat.core.id.Identity;
 import org.olat.core.util.StringHelper;
-import org.olat.modules.forms.EvaluationFormManager;
 import org.olat.modules.forms.EvaluationFormSession;
-import org.olat.modules.forms.EvaluationFormSessionRef;
-import org.springframework.beans.factory.annotation.Autowired;
 
 /**
  * 
@@ -39,16 +35,12 @@ import org.springframework.beans.factory.annotation.Autowired;
  */
 public class SessionInformationLegendNameGenerator implements LegendNameGenerator {
 	
-	private Map<Long, String> sessionKeyToName;
+	private Map<EvaluationFormSession, String> sessionKeyToName;
 
-	private final List<? extends EvaluationFormSessionRef> sessionRefs;
+	private final List<? extends EvaluationFormSession> sessions;
 	
-	@Autowired
-	private EvaluationFormManager evaluationFormManager;
-	
-	public SessionInformationLegendNameGenerator(List<? extends EvaluationFormSessionRef> sessionRefs) {
-		this.sessionRefs = sessionRefs;
-		CoreSpringFactory.autowireObject(this);
+	public SessionInformationLegendNameGenerator(List<EvaluationFormSession> sessions) {
+		this.sessions = sessions;
 	}
 
 	@Override
@@ -58,15 +50,14 @@ public class SessionInformationLegendNameGenerator implements LegendNameGenerato
 		if (sessionKeyToName == null) {
 			initSessionKeyToName();
 		}
-		return sessionKeyToName.get(session.getKey());
+		return sessionKeyToName.get(session);
 	}
 
 	private void initSessionKeyToName() {
 		sessionKeyToName = new HashMap<>();
-		List<EvaluationFormSession> sessions = evaluationFormManager.loadSessionsByKey(sessionRefs, 0, -1);
 		for (EvaluationFormSession session: sessions) {
 			String name = conacatName(session.getFirstname(), session.getLastname());
-			sessionKeyToName.put(session.getKey(), name);
+			sessionKeyToName.put(session, name);
 		}
 	}
 
diff --git a/src/main/java/org/olat/modules/forms/ui/SessionInformationsController.java b/src/main/java/org/olat/modules/forms/ui/SessionInformationsController.java
index 98c02ce74d2..43461193de3 100644
--- a/src/main/java/org/olat/modules/forms/ui/SessionInformationsController.java
+++ b/src/main/java/org/olat/modules/forms/ui/SessionInformationsController.java
@@ -37,7 +37,7 @@ import org.olat.core.util.CodeHelper;
 import org.olat.core.util.StringHelper;
 import org.olat.modules.forms.EvaluationFormManager;
 import org.olat.modules.forms.EvaluationFormSession;
-import org.olat.modules.forms.EvaluationFormSessionRef;
+import org.olat.modules.forms.model.jpa.EvaluationFormResponses;
 import org.olat.modules.forms.model.xml.SessionInformations;
 import org.olat.modules.forms.model.xml.SessionInformations.InformationType;
 import org.olat.modules.forms.ui.model.EvaluationFormResponseController;
@@ -160,16 +160,9 @@ public class SessionInformationsController extends FormBasicController implement
 	}
 
 	@Override
-	public void loadResponse(EvaluationFormSessionRef session) {
-		EvaluationFormSession loadedSession;
-		if (session instanceof EvaluationFormSession) {
-			loadedSession = (EvaluationFormSession) session;
-		} else {
-			loadedSession = evaluationFormManager.loadSessionByKey(session);
-		}
-		
+	public void initResponse(EvaluationFormSession session, EvaluationFormResponses responses) {
 		for (SessionInformationWrapper wrapper: sessionInformationWrappers) {
-			String value = getValue(loadedSession, wrapper.getInformationType());
+			String value = getValue(session, wrapper.getInformationType());
 			wrapper.getInformationEl().setValue(value);
 		}
 	}
diff --git a/src/main/java/org/olat/modules/forms/ui/SingleChoiceController.java b/src/main/java/org/olat/modules/forms/ui/SingleChoiceController.java
index bea9d4a6199..01131058b12 100644
--- a/src/main/java/org/olat/modules/forms/ui/SingleChoiceController.java
+++ b/src/main/java/org/olat/modules/forms/ui/SingleChoiceController.java
@@ -33,7 +33,7 @@ import org.olat.core.util.StringHelper;
 import org.olat.modules.forms.EvaluationFormManager;
 import org.olat.modules.forms.EvaluationFormResponse;
 import org.olat.modules.forms.EvaluationFormSession;
-import org.olat.modules.forms.EvaluationFormSessionRef;
+import org.olat.modules.forms.model.jpa.EvaluationFormResponses;
 import org.olat.modules.forms.model.xml.Choice;
 import org.olat.modules.forms.model.xml.SingleChoice;
 import org.olat.modules.forms.ui.model.EvaluationFormResponseController;
@@ -120,8 +120,8 @@ public class SingleChoiceController extends FormBasicController implements Evalu
 	}
 
 	@Override
-	public void loadResponse(EvaluationFormSessionRef session) {
-		response = evaluationFormManager.loadResponse(singleChoice.getId(), session);
+	public void initResponse(EvaluationFormSession session, EvaluationFormResponses responses) {
+		response = responses.getResponse(session, singleChoice.getId());
 		if (response != null) {
 			for (Choice choice: singleChoice.getChoices().asList()) {
 				if (choice.getId().equals(response.getStringuifiedResponse())) {
diff --git a/src/main/java/org/olat/modules/forms/ui/TextInputController.java b/src/main/java/org/olat/modules/forms/ui/TextInputController.java
index 4afaffabbdf..a349a12c201 100644
--- a/src/main/java/org/olat/modules/forms/ui/TextInputController.java
+++ b/src/main/java/org/olat/modules/forms/ui/TextInputController.java
@@ -34,7 +34,7 @@ import org.olat.core.util.StringHelper;
 import org.olat.modules.forms.EvaluationFormManager;
 import org.olat.modules.forms.EvaluationFormResponse;
 import org.olat.modules.forms.EvaluationFormSession;
-import org.olat.modules.forms.EvaluationFormSessionRef;
+import org.olat.modules.forms.model.jpa.EvaluationFormResponses;
 import org.olat.modules.forms.model.xml.TextInput;
 import org.olat.modules.forms.ui.model.EvaluationFormResponseController;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -135,8 +135,8 @@ public class TextInputController extends FormBasicController implements Evaluati
 	}
 
 	@Override
-	public void loadResponse(EvaluationFormSessionRef session) {
-		response = evaluationFormManager.loadResponse(textInput.getId(), session);
+	public void initResponse(EvaluationFormSession session, EvaluationFormResponses responses) {
+		response = responses.getResponse(session, textInput.getId());
 		if (response != null) {
 			if (singleRow) {
 				singleRowEl.setValue(response.getStringuifiedResponse());
diff --git a/src/main/java/org/olat/modules/forms/ui/model/EvaluationFormComponentElement.java b/src/main/java/org/olat/modules/forms/ui/model/EvaluationFormComponentElement.java
index 4de544c92e4..9b8b1931185 100644
--- a/src/main/java/org/olat/modules/forms/ui/model/EvaluationFormComponentElement.java
+++ b/src/main/java/org/olat/modules/forms/ui/model/EvaluationFormComponentElement.java
@@ -25,7 +25,7 @@ import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.Component;
 import org.olat.core.gui.components.form.flexible.FormItem;
 import org.olat.modules.forms.EvaluationFormSession;
-import org.olat.modules.forms.EvaluationFormSessionRef;
+import org.olat.modules.forms.model.jpa.EvaluationFormResponses;
 import org.olat.modules.portfolio.ui.editor.PageRunElement;
 import org.olat.modules.portfolio.ui.editor.ValidationMessage;
 
@@ -76,7 +76,7 @@ public class EvaluationFormComponentElement implements EvaluationFormExecutionEl
 	}
 
 	@Override
-	public void loadResponse(EvaluationFormSessionRef session) {
+	public void initResponse(EvaluationFormSession session, EvaluationFormResponses responses) {
 		//
 	}
 
diff --git a/src/main/java/org/olat/modules/forms/ui/model/EvaluationFormExecutionElement.java b/src/main/java/org/olat/modules/forms/ui/model/EvaluationFormExecutionElement.java
index 789918eaae7..20de327ce4b 100644
--- a/src/main/java/org/olat/modules/forms/ui/model/EvaluationFormExecutionElement.java
+++ b/src/main/java/org/olat/modules/forms/ui/model/EvaluationFormExecutionElement.java
@@ -21,7 +21,7 @@ package org.olat.modules.forms.ui.model;
 
 import org.olat.core.gui.components.form.flexible.FormItem;
 import org.olat.modules.forms.EvaluationFormSession;
-import org.olat.modules.forms.EvaluationFormSessionRef;
+import org.olat.modules.forms.model.jpa.EvaluationFormResponses;
 import org.olat.modules.portfolio.ui.editor.PageRunElement;
 
 /**
@@ -40,7 +40,7 @@ public interface EvaluationFormExecutionElement extends PageRunElement {
 	
 	public boolean hasResponse();
 	
-	public void loadResponse(EvaluationFormSessionRef session);
+	public void initResponse(EvaluationFormSession session, EvaluationFormResponses responses);
 	
 	public void saveResponse(EvaluationFormSession session);
 
diff --git a/src/main/java/org/olat/modules/forms/ui/model/EvaluationFormResponseController.java b/src/main/java/org/olat/modules/forms/ui/model/EvaluationFormResponseController.java
index abecff8a4ab..fb035e63dcb 100644
--- a/src/main/java/org/olat/modules/forms/ui/model/EvaluationFormResponseController.java
+++ b/src/main/java/org/olat/modules/forms/ui/model/EvaluationFormResponseController.java
@@ -22,7 +22,7 @@ package org.olat.modules.forms.ui.model;
 import org.olat.core.gui.components.form.flexible.FormItem;
 import org.olat.core.gui.control.Controller;
 import org.olat.modules.forms.EvaluationFormSession;
-import org.olat.modules.forms.EvaluationFormSessionRef;
+import org.olat.modules.forms.model.jpa.EvaluationFormResponses;
 
 /**
  * 
@@ -36,7 +36,7 @@ public interface EvaluationFormResponseController extends Controller {
 	
 	public boolean hasResponse();
 	
-	public void loadResponse(EvaluationFormSessionRef session);
+	public void initResponse(EvaluationFormSession session, EvaluationFormResponses responses);
 	
 	public void saveResponse(EvaluationFormSession session);
 	
diff --git a/src/main/java/org/olat/modules/forms/ui/model/EvaluationFormResponseControllerElement.java b/src/main/java/org/olat/modules/forms/ui/model/EvaluationFormResponseControllerElement.java
index 9b108c1df1d..c9be4a125a3 100644
--- a/src/main/java/org/olat/modules/forms/ui/model/EvaluationFormResponseControllerElement.java
+++ b/src/main/java/org/olat/modules/forms/ui/model/EvaluationFormResponseControllerElement.java
@@ -25,7 +25,7 @@ import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.Component;
 import org.olat.core.gui.components.form.flexible.FormItem;
 import org.olat.modules.forms.EvaluationFormSession;
-import org.olat.modules.forms.EvaluationFormSessionRef;
+import org.olat.modules.forms.model.jpa.EvaluationFormResponses;
 import org.olat.modules.portfolio.ui.editor.ValidatingController;
 import org.olat.modules.portfolio.ui.editor.ValidationMessage;
 
@@ -77,8 +77,8 @@ public class EvaluationFormResponseControllerElement implements EvaluationFormEx
 	}
 	
 	@Override
-	public void loadResponse(EvaluationFormSessionRef session) {
-		controller.loadResponse(session);
+	public void initResponse(EvaluationFormSession session, EvaluationFormResponses responses) {
+		controller.initResponse(session, responses);;
 	}
 
 	@Override
diff --git a/src/test/java/org/olat/modules/forms/manager/EvaluationFormResponseDAOTest.java b/src/test/java/org/olat/modules/forms/manager/EvaluationFormResponseDAOTest.java
index 32bd00c0f5d..0353475b22d 100644
--- a/src/test/java/org/olat/modules/forms/manager/EvaluationFormResponseDAOTest.java
+++ b/src/test/java/org/olat/modules/forms/manager/EvaluationFormResponseDAOTest.java
@@ -24,6 +24,8 @@ import static org.assertj.core.api.Assertions.assertThat;
 import java.math.BigDecimal;
 import java.nio.file.Path;
 import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 import java.util.UUID;
 import java.util.stream.Collectors;
@@ -125,6 +127,26 @@ public class EvaluationFormResponseDAOTest extends OlatTestCase {
 				.doesNotContain(otherResponse);
 	}
 	
+	@Test
+	public void shouldLoadResponsesBySessions() {
+		EvaluationFormSurvey survey = evaTestHelper.createSurvey();
+		EvaluationFormSession session1 = evaTestHelper.createSession(survey);
+		EvaluationFormResponse response11 = evaTestHelper.createResponse(session1);
+		EvaluationFormResponse response12 = evaTestHelper.createResponse(session1);
+		EvaluationFormSession session2 = evaTestHelper.createSession(survey);
+		EvaluationFormResponse response21 = evaTestHelper.createResponse(session2);
+		EvaluationFormSession otherSession = evaTestHelper.createSession();
+		EvaluationFormResponse otherResponse = evaTestHelper.createResponse(otherSession);
+		dbInstance.commit();
+		
+		List<EvaluationFormSession> sessions = Arrays.asList(session1, session2);
+		List<EvaluationFormResponse> loadedResponses = sut.loadResponsesBySessions(sessions);
+		
+		assertThat(loadedResponses)
+				.contains(response11, response12, response21)
+				.doesNotContain(otherResponse);
+	}
+	
 	@Test
 	public void shouldDeleteResponses() {
 		EvaluationFormSession session = evaTestHelper.createSession();
@@ -134,14 +156,14 @@ public class EvaluationFormResponseDAOTest extends OlatTestCase {
 		createResponse(session, responseIdentifier);
 		dbInstance.commit();
 		
-		List<EvaluationFormResponse> responses = sut.loadResponses(responseIdentifier, session);
+		List<EvaluationFormResponse> responses = sut.loadResponsesBySessions(Collections.singletonList(session));
 		assertThat(responses).hasSize(3);
 		
 		List<Long> keys = responses.stream().map(EvaluationFormResponse::getKey).collect(Collectors.toList());
 		sut.deleteResponses(keys);
 		dbInstance.commit();
 		
-		responses = sut.loadResponses(responseIdentifier, session);
+		responses = sut.loadResponsesBySessions(Collections.singletonList(session));
 		assertThat(responses).hasSize(0);
 	}
 	
-- 
GitLab