From 2b9e636b04f72309b0f68f8cdba37600789d2692 Mon Sep 17 00:00:00 2001
From: srosse <stephane.rosse@frentix.com>
Date: Fri, 11 Jan 2019 08:16:20 +0100
Subject: [PATCH] OO-3785: update hibernate to version 5.4, fix efficiency
 statements

---
 pom.xml                                       |   2 +-
 .../manager/EfficiencyStatementManager.java   | 275 ++++++-------
 .../model/UserEfficiencyStatementImpl.hbm.xml | 142 -------
 .../model/UserEfficiencyStatementImpl.java    | 100 ++++-
 .../model/UserEfficiencyStatementLight.java   |  95 ++++-
 .../UserEfficiencyStatementRepoImpl.java      | 205 ----------
 .../UserEfficiencyStatementStandalone.java    |  93 ++++-
 src/main/resources/META-INF/persistence.xml   |  11 +-
 .../EfficiencyStatementManagerTest.java       | 374 +++++++++++++++++-
 .../olat/restapi/EfficiencyStatementTest.java |  21 +-
 10 files changed, 771 insertions(+), 547 deletions(-)
 delete mode 100644 src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementImpl.hbm.xml
 delete mode 100644 src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementRepoImpl.java

diff --git a/pom.xml b/pom.xml
index 97178f5c4c6..a2240919586 100644
--- a/pom.xml
+++ b/pom.xml
@@ -63,7 +63,7 @@
 		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 		<targetJdk>1.8</targetJdk>
 		<org.springframework.version>5.1.3.RELEASE</org.springframework.version>
-		<org.hibernate.version>5.3.7.Final</org.hibernate.version>
+		<org.hibernate.version>5.4.0.Final</org.hibernate.version>
 		<com.sun.jersey.version>1.19.4</com.sun.jersey.version>
 		<apache.cxf>3.2.7</apache.cxf>
 		<jackson.version>2.9.7</jackson.version>
diff --git a/src/main/java/org/olat/course/assessment/manager/EfficiencyStatementManager.java b/src/main/java/org/olat/course/assessment/manager/EfficiencyStatementManager.java
index 9b58b858ae1..c7a37272f0d 100644
--- a/src/main/java/org/olat/course/assessment/manager/EfficiencyStatementManager.java
+++ b/src/main/java/org/olat/course/assessment/manager/EfficiencyStatementManager.java
@@ -112,8 +112,13 @@ public class EfficiencyStatementManager implements UserDataDeletable, UserDataEx
 
 	public UserEfficiencyStatement createUserEfficiencyStatement(Date creationDate, Float score, Boolean passed, Identity identity, OLATResource resource) {
 		UserEfficiencyStatementImpl efficiencyProperty = new UserEfficiencyStatementImpl();
-		efficiencyProperty.setCreationDate(creationDate);
-		efficiencyProperty.setLastModified(new Date());
+		if(creationDate == null) {
+			efficiencyProperty.setCreationDate(new Date());
+			efficiencyProperty.setLastModified(efficiencyProperty.getCreationDate());
+		} else {
+			efficiencyProperty.setCreationDate(creationDate);
+			efficiencyProperty.setLastModified(new Date());
+		}
 		efficiencyProperty.setScore(score);
 		efficiencyProperty.setPassed(passed);
 
@@ -203,6 +208,7 @@ public class EfficiencyStatementManager implements UserDataDeletable, UserDataEx
 			if (efficiencyProperty == null) {
 				// create new
 				efficiencyProperty = new UserEfficiencyStatementImpl();
+				efficiencyProperty.setCreationDate(new Date());
 				efficiencyProperty.setIdentity(assessedIdentity);
 				efficiencyProperty.setCourseRepoKey(repoEntry.getKey());
 				if(repoEntry != null) {
@@ -350,8 +356,8 @@ public class EfficiencyStatementManager implements UserDataDeletable, UserDataEx
 	}
 	
 	public EfficiencyStatement getUserEfficiencyStatementByResourceKey(Long resourceKey, Identity identity){
-		StringBuilder sb = new StringBuilder();
-		sb.append("select statement from ").append(UserEfficiencyStatementStandalone.class.getName()).append(" as statement ")
+		StringBuilder sb = new StringBuilder(256);
+		sb.append("select statement from effstatementstandalone as statement")
 		  .append(" where statement.identity.key=:identityKey and statement.resourceKey=:resourceKey");
 
 		List<UserEfficiencyStatementStandalone> statement = dbInstance.getCurrentEntityManager()
@@ -366,52 +372,26 @@ public class EfficiencyStatementManager implements UserDataDeletable, UserDataEx
 	}
 	
 
-	public UserEfficiencyStatementImpl getUserEfficiencyStatementFull(RepositoryEntryRef courseRepoEntry, Identity identity) {
-		try {
-			StringBuilder sb = new StringBuilder();
-			sb.append("select statement from ").append(UserEfficiencyStatementImpl.class.getName()).append(" as statement ")
-			  .append(" where statement.identity.key=:identityKey and statement.courseRepoKey=:repoKey");
-
-			List<UserEfficiencyStatementImpl> statement = dbInstance.getCurrentEntityManager()
-					.createQuery(sb.toString(), UserEfficiencyStatementImpl.class)
-					.setParameter("identityKey", identity.getKey())
-					.setParameter("repoKey", courseRepoEntry.getKey())
-					.getResultList();
-			if(statement.isEmpty()) {
-				return null;
-			}
-			return statement.get(0);
-		} catch (Exception e) {
-			log.error("Cannot retrieve efficiency statement: " + courseRepoEntry.getKey() + " from " + identity, e);
-			return null;
-		}
-	}
-	
-	public UserEfficiencyStatementImpl getUserEfficiencyStatementFullByResourceKey(Long resourceKey, Identity identity) {
-		try {
-			StringBuilder sb = new StringBuilder();
-			sb.append("select statement from ").append(UserEfficiencyStatementImpl.class.getName()).append(" as statement ")
-			  .append(" where statement.identity.key=:identityKey")
-			  .append(" and statement.resource.key=:resourceKey");
+	public UserEfficiencyStatementImpl getUserEfficiencyStatementFull(RepositoryEntryRef courseRepoEntry, IdentityRef identity) {
+		StringBuilder sb = new StringBuilder(256);
+		sb.append("select statement from effstatement as statement ")
+		  .append(" left join fetch statement.resource as resource")
+		  .append(" where statement.identity.key=:identityKey and statement.courseRepoKey=:repoKey");
 
-			List<UserEfficiencyStatementImpl> statement = dbInstance.getCurrentEntityManager()
-					.createQuery(sb.toString(), UserEfficiencyStatementImpl.class)
-					.setParameter("identityKey", identity.getKey())
-					.setParameter("resourceKey", resourceKey)
-					.getResultList();
-			if(statement.isEmpty()) {
-				return null;
-			}
-			return statement.get(0);
-		} catch (Exception e) {
-			log.error("Cannot retrieve efficiency statement: " + resourceKey + " from " + identity, e);
+		List<UserEfficiencyStatementImpl> statement = dbInstance.getCurrentEntityManager()
+				.createQuery(sb.toString(), UserEfficiencyStatementImpl.class)
+				.setParameter("identityKey", identity.getKey())
+				.setParameter("repoKey", courseRepoEntry.getKey())
+				.getResultList();
+		if(statement.isEmpty()) {
 			return null;
 		}
+		return statement.get(0);
 	}
 	
 	public boolean hasUserEfficiencyStatement(Long courseRepoEntryKey, IdentityRef identity) {
 		StringBuilder sb = new StringBuilder();
-		sb.append("select statement.key from ").append(UserEfficiencyStatementLight.class.getName()).append(" as statement ")
+		sb.append("select statement.key from effstatementlight as statement")
 		  .append(" where statement.identity.key=:identityKey and statement.courseRepoKey=:repoKey");
 
 		List<Number> count = dbInstance.getCurrentEntityManager()
@@ -421,28 +401,24 @@ public class EfficiencyStatementManager implements UserDataDeletable, UserDataEx
 				.setFirstResult(0)
 				.setMaxResults(1)
 				.getResultList();
-		return count != null && count.size() > 0;
+		return count != null && !count.isEmpty() && count.get(0) != null;
 	}
 	
 	public UserEfficiencyStatement getUserEfficiencyStatementLightByRepositoryEntry(RepositoryEntryRef courseRepo, IdentityRef identity) {
-		try {
-			StringBuilder sb = new StringBuilder();
-			sb.append("select statement from ").append(UserEfficiencyStatementLight.class.getName()).append(" as statement ")
-			  .append(" where statement.identity.key=:identityKey and statement.courseRepoKey=:repoKey");
+		StringBuilder sb = new StringBuilder(256);
+		sb.append("select statement from effstatementlight as statement")
+		  .append(" left join fetch statement.resource as resource")
+		  .append(" where statement.identity.key=:identityKey and statement.courseRepoKey=:repoKey");
 
-			List<UserEfficiencyStatement> statement = dbInstance.getCurrentEntityManager()
-					.createQuery(sb.toString(), UserEfficiencyStatement.class)
-					.setParameter("identityKey", identity.getKey())
-					.setParameter("repoKey", courseRepo.getKey())
-					.getResultList();
-			if(statement.isEmpty()) {
-				return null;
-			}
-			return statement.get(0);
-		} catch (Exception e) {
-			log.error("Cannot retrieve efficiency statement: " + courseRepo.getKey() + " from " + identity, e);
+		List<UserEfficiencyStatement> statement = dbInstance.getCurrentEntityManager()
+				.createQuery(sb.toString(), UserEfficiencyStatement.class)
+				.setParameter("identityKey", identity.getKey())
+				.setParameter("repoKey", courseRepo.getKey())
+				.getResultList();
+		if(statement.isEmpty()) {
 			return null;
 		}
+		return statement.get(0);
 	}
 	
 	public List<UserEfficiencyStatement> getUserEfficiencyStatementLight(IdentityRef student, List<RepositoryEntry> courses) {
@@ -450,9 +426,10 @@ public class EfficiencyStatementManager implements UserDataDeletable, UserDataEx
 			return Collections.emptyList();
 		}
 		
-		StringBuilder sb = new StringBuilder();
-		sb.append("select statement from ").append(UserEfficiencyStatementLight.class.getName()).append(" as statement ")
-		  .append(" where statement.identity.key=:studentKey and statement.resource.key in (:courseResourcesKey)");
+		StringBuilder sb = new StringBuilder(256);
+		sb.append("select statement from effstatementlight as statement")
+		  .append(" inner join fetch statement.resource as resource")
+		  .append(" where statement.identity.key=:studentKey and resource.key in (:courseResourcesKey)");
 		
 		List<Long> coursesKey = new ArrayList<>();
 		for(RepositoryEntry course:courses) {
@@ -468,7 +445,8 @@ public class EfficiencyStatementManager implements UserDataDeletable, UserDataEx
 	
 	public List<UserEfficiencyStatement> getUserEfficiencyStatementLight(IdentityRef student) {
 		StringBuilder sb = new StringBuilder();
-		sb.append("select statement from ").append(UserEfficiencyStatementLight.class.getName()).append(" as statement ")
+		sb.append("select statement from effstatementlight as statement")
+		  .append(" left join fetch statement.resource as resource")
 		  .append(" where statement.identity.key=:studentKey");
 
 		return dbInstance.getCurrentEntityManager()
@@ -483,8 +461,9 @@ public class EfficiencyStatementManager implements UserDataDeletable, UserDataEx
 		}
 		
 		StringBuilder sb = new StringBuilder();
-		sb.append("select statement from ").append(UserEfficiencyStatementLight.class.getName()).append(" as statement ")
-		  .append(" where statement.resource.key=:resourcesKey");
+		sb.append("select statement from effstatementlight as statement")
+		  .append(" inner join fetch statement.resource as resource")
+		  .append(" where resource.key=:resourcesKey");
 		return dbInstance.getCurrentEntityManager()
 				.createQuery(sb.toString(), UserEfficiencyStatement.class)
 				.setParameter("resourcesKey",course.getOlatResource().getKey())
@@ -502,8 +481,9 @@ public class EfficiencyStatementManager implements UserDataDeletable, UserDataEx
 		}
 		
 		StringBuilder sb = new StringBuilder();
-		sb.append("select statement from ").append(UserEfficiencyStatementLight.class.getName()).append(" as statement ")
-		  .append(" where statement.resource.key in (:courseResourcesKey)");
+		sb.append("select statement from effstatementlight as statement ")
+		  .append(" inner join fetch statement.resource as resource")
+		  .append(" where resource.key in (:courseResourcesKey)");
 		return dbInstance.getCurrentEntityManager()
 				.createQuery(sb.toString(), UserEfficiencyStatement.class)
 				.setParameter("courseResourcesKey", resourcesKey)
@@ -511,49 +491,40 @@ public class EfficiencyStatementManager implements UserDataDeletable, UserDataEx
 	}
 	
 	public UserEfficiencyStatement getUserEfficiencyStatementLightByResource(Long resourceKey, IdentityRef identity) {
-		try {
-			StringBuilder sb = new StringBuilder();
-			sb.append("select statement from ").append(UserEfficiencyStatementLight.class.getName()).append(" as statement ")
-			  .append(" where statement.identity.key=:identityKey and statement.resource.key=:resourceKey");
+		StringBuilder sb = new StringBuilder(256);
+		sb.append("select statement from effstatementstandalone as statement")
+		  .append(" where statement.identity.key=:identityKey and statement.resourceKey=:resourceKey");
 
-			List<UserEfficiencyStatement> statement = dbInstance.getCurrentEntityManager()
-					.createQuery(sb.toString(), UserEfficiencyStatement.class)
-					.setParameter("identityKey", identity.getKey())
-					.setParameter("resourceKey", resourceKey)
-					.getResultList();
-			if(statement.isEmpty()) {
-				return null;
-			}
-			return statement.get(0);
-		} catch (Exception e) {
-			log.error("Cannot retrieve efficiency statement: " + resourceKey + " from " + identity, e);
+		List<UserEfficiencyStatement> statement = dbInstance.getCurrentEntityManager()
+				.createQuery(sb.toString(), UserEfficiencyStatement.class)
+				.setParameter("identityKey", identity.getKey())
+				.setParameter("resourceKey", resourceKey)
+				.getResultList();
+		if(statement.isEmpty()) {
 			return null;
 		}
+		return statement.get(0);
 	}
 	
 	public EfficiencyStatement getUserEfficiencyStatementByKey(Long key) {
-		try {
-			StringBuilder sb = new StringBuilder();
-			sb.append("select statement from ").append(UserEfficiencyStatementImpl.class.getName()).append(" as statement ")
-			  .append(" where statement.key=:key");
-
-			List<UserEfficiencyStatementImpl> statement = dbInstance.getCurrentEntityManager()
-					.createQuery(sb.toString(), UserEfficiencyStatementImpl.class)
-					.setParameter("key", key)
-					.getResultList();
-			if(statement.isEmpty()) {
-				return null;
-			}
-			return (EfficiencyStatement)xstream.fromXML(statement.get(0).getStatementXml());
-		} catch (Exception e) {
-			log.error("Cannot retrieve efficiency statement: " + key, e);
+		StringBuilder sb = new StringBuilder();
+		sb.append("select statement from effstatement as statement ")
+		  .append(" where statement.key=:key");
+
+		List<UserEfficiencyStatementImpl> statement = dbInstance.getCurrentEntityManager()
+				.createQuery(sb.toString(), UserEfficiencyStatementImpl.class)
+				.setParameter("key", key)
+				.getResultList();
+		if(statement.isEmpty()) {
 			return null;
 		}
+		return (EfficiencyStatement)xstream.fromXML(statement.get(0).getStatementXml());
 	}
 	
 	public UserEfficiencyStatementLight getUserEfficiencyStatementLightByKey(Long key) {
 		StringBuilder sb = new StringBuilder();
-		sb.append("select statement from ").append(UserEfficiencyStatementLight.class.getName()).append(" as statement ")
+		sb.append("select statement from effstatementlight as statement")
+		  .append(" left join fetch statement.resource as resource")
 		  .append(" where statement.key=:key");
 
 		List<UserEfficiencyStatementLight> statement = dbInstance.getCurrentEntityManager()
@@ -604,9 +575,7 @@ public class EfficiencyStatementManager implements UserDataDeletable, UserDataEx
 			Map<String,Object> nodeData = iter.next();
 			Boolean selectable = (Boolean)nodeData.get(AssessmentHelper.KEY_SELECTABLE);
 			if(selectable != null && selectable.booleanValue()) {
-				if(nodeData.containsKey(AssessmentHelper.KEY_SCORE)) {
-					count++;
-				} else if (nodeData.containsKey(AssessmentHelper.KEY_PASSED)) {
+				if(nodeData.containsKey(AssessmentHelper.KEY_SCORE) || nodeData.containsKey(AssessmentHelper.KEY_PASSED)) {
 					count++;
 				}
 			}
@@ -647,60 +616,49 @@ public class EfficiencyStatementManager implements UserDataDeletable, UserDataEx
 		}
 		return null;
 	}
-
 	
 	/**
 	 * Find all efficiency statements for a specific user
 	 * @param identity
 	 * @return List of efficiency statements
 	 */
-	protected List<EfficiencyStatement> findEfficiencyStatements(Identity identity) {
+	protected List<EfficiencyStatement> findEfficiencyStatements(IdentityRef identity) {
 		List<EfficiencyStatement> efficiencyStatements = new ArrayList<>();
-		try {
-			StringBuilder sb = new StringBuilder();
-			sb.append("select statement from ").append(UserEfficiencyStatementImpl.class.getName()).append(" as statement ")
-			  .append(" where statement.identity.key=:identityKey");
+		StringBuilder sb = new StringBuilder();
+		sb.append("select statement from effstatement as statement")
+		  .append(" where statement.identity.key=:identityKey");
 
-			List<UserEfficiencyStatementImpl> statements = dbInstance.getCurrentEntityManager()
-					.createQuery(sb.toString(), UserEfficiencyStatementImpl.class)
-					.setParameter("identityKey", identity.getKey())
-					.getResultList();
-			for(UserEfficiencyStatementImpl statement:statements) {
-				if(StringHelper.containsNonWhitespace(statement.getStatementXml())) {
-					EfficiencyStatement s = (EfficiencyStatement)xstream.fromXML(statement.getStatementXml());
-					efficiencyStatements.add(s);
-				}
+		List<UserEfficiencyStatementImpl> statements = dbInstance.getCurrentEntityManager()
+				.createQuery(sb.toString(), UserEfficiencyStatementImpl.class)
+				.setParameter("identityKey", identity.getKey())
+				.getResultList();
+		for(UserEfficiencyStatementImpl statement:statements) {
+			if(StringHelper.containsNonWhitespace(statement.getStatementXml())) {
+				EfficiencyStatement s = (EfficiencyStatement)xstream.fromXML(statement.getStatementXml());
+				efficiencyStatements.add(s);
 			}
-
-		} catch (Exception e) {
-			log.error("findEfficiencyStatements: " + identity, e);
 		}
 		return efficiencyStatements;
 	}
 	
-	public List<UserEfficiencyStatementLight> findEfficiencyStatementsLight(Identity identity) {
-		try {
-			StringBuilder sb = new StringBuilder();
-			sb.append("select statement from ").append(UserEfficiencyStatementLight.class.getName()).append(" as statement ")
-				.append(" left join fetch statement.resource resource")
-			  .append(" where statement.identity.key=:identityKey");
+	public List<UserEfficiencyStatementLight> findEfficiencyStatementsLight(IdentityRef identity) {
+		StringBuilder sb = new StringBuilder(256);
+		sb.append("select statement from effstatementlight as statement")
+		  .append(" left join fetch statement.resource resource")
+		  .append(" where statement.identity.key=:identityKey");
 
-			return dbInstance.getCurrentEntityManager()
-					.createQuery(sb.toString(), UserEfficiencyStatementLight.class)
-					.setParameter("identityKey", identity.getKey())
-					.getResultList();
-		} catch (Exception e) {
-			log.error("findEfficiencyStatements: " + identity, e);
-			return Collections.emptyList();
-		}
+		return dbInstance.getCurrentEntityManager()
+				.createQuery(sb.toString(), UserEfficiencyStatementLight.class)
+				.setParameter("identityKey", identity.getKey())
+				.getResultList();
 	}
 	
 	public List<UserEfficiencyStatementLight> findEfficiencyStatementsLight(List<Long> keys) {
 		if(keys == null || keys.isEmpty()) return Collections.emptyList();
 		
-		StringBuilder sb = new StringBuilder();
-		sb.append("select statement from ").append(UserEfficiencyStatementLight.class.getName()).append(" as statement ")
-			.append(" left join fetch statement.resource resource")
+		StringBuilder sb = new StringBuilder(256);
+		sb.append("select statement from effstatementlight as statement")
+		  .append(" left join fetch statement.resource resource")
 		  .append(" where statement.key in (:keys)");
 
 		return dbInstance.getCurrentEntityManager()
@@ -719,19 +677,14 @@ public class EfficiencyStatementManager implements UserDataDeletable, UserDataEx
 	 * @return List of identities
 	 */
 	protected List<Identity> findIdentitiesWithEfficiencyStatements(Long courseRepoEntryKey) {
-		try {
-			StringBuilder sb = new StringBuilder();
-			sb.append("select distinct(statement.identity) from ").append(UserEfficiencyStatementImpl.class.getName()).append(" as statement ")
-			  .append(" where statement.courseRepoKey=:repoKey");
+		StringBuilder sb = new StringBuilder();
+		sb.append("select distinct(statement.identity) from effstatement as statement ")
+		  .append(" where statement.courseRepoKey=:repoKey");
 
-			return dbInstance.getCurrentEntityManager()
-					.createQuery(sb.toString(), Identity.class)
-					.setParameter("repoKey", courseRepoEntryKey)
-					.getResultList();
-		} catch (Exception e) {
-			log.error("findIdentitiesWithEfficiencyStatements: " + courseRepoEntryKey, e);
-			return Collections.emptyList();
-		}
+		return dbInstance.getCurrentEntityManager()
+				.createQuery(sb.toString(), Identity.class)
+				.setParameter("repoKey", courseRepoEntryKey)
+				.getResultList();
 	}
 	
 	/**
@@ -740,20 +693,16 @@ public class EfficiencyStatementManager implements UserDataDeletable, UserDataEx
 	 * @return int number of deleted efficiency statements
 	 */
 	public void deleteEfficiencyStatementsFromCourse(Long courseRepoEntryKey) {
-		try {
-			StringBuilder sb = new StringBuilder();
-			sb.append("select statement from ").append(UserEfficiencyStatementImpl.class.getName()).append(" as statement ")
-			  .append(" where statement.courseRepoKey=:repoKey");
-
-			List<UserEfficiencyStatementImpl> statements = dbInstance.getCurrentEntityManager()
-					.createQuery(sb.toString(), UserEfficiencyStatementImpl.class)
-					.setParameter("repoKey", courseRepoEntryKey)
-					.getResultList();
-			for(UserEfficiencyStatementImpl statement:statements) {
-				dbInstance.deleteObject(statement);
-			}
-		} catch (Exception e) {
-			log.error("deleteEfficiencyStatementsFromCourse: " + courseRepoEntryKey, e);
+		StringBuilder sb = new StringBuilder();
+		sb.append("select statement from effstatement as statement ")
+		  .append(" where statement.courseRepoKey=:repoKey");
+
+		List<UserEfficiencyStatementImpl> statements = dbInstance.getCurrentEntityManager()
+				.createQuery(sb.toString(), UserEfficiencyStatementImpl.class)
+				.setParameter("repoKey", courseRepoEntryKey)
+				.getResultList();
+		for(UserEfficiencyStatementImpl statement:statements) {
+			dbInstance.deleteObject(statement);
 		}
 	}
 
@@ -842,7 +791,7 @@ public class EfficiencyStatementManager implements UserDataDeletable, UserDataEx
 	public void deleteEfficientyStatement(Identity identity) {
 		try {
 			StringBuilder sb = new StringBuilder();
-			sb.append("delete from ").append(UserEfficiencyStatementImpl.class.getName()).append(" as statement ")
+			sb.append("delete from effstatement as statement ")
 			  .append(" where statement.identity.key=:identityKey");
 
 			int numOfDeletedStatements = dbInstance.getCurrentEntityManager()
diff --git a/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementImpl.hbm.xml b/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementImpl.hbm.xml
deleted file mode 100644
index 5f897c601ed..00000000000
--- a/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementImpl.hbm.xml
+++ /dev/null
@@ -1,142 +0,0 @@
-<?xml version="1.0"?>
-<!DOCTYPE hibernate-mapping PUBLIC
-	"-//Hibernate/Hibernate Mapping DTD//EN"
-	"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
-<hibernate-mapping default-lazy="false">
-  
-  <class name="org.olat.course.assessment.model.UserEfficiencyStatementImpl" table="o_as_eff_statement">
-
-	<id name="key" type="long" column="id"	unsaved-value="null">
-		<generator class="enhanced-sequence">
-			<param name="sequence_name">hibernate_unique_key</param>
-			<param name="force_table_use">true</param>
-			<param name="optimizer">legacy-hilo</param>
-			<param name="value_column">next_hi</param>
-			<param name="increment_size">32767</param>
-			<param name="initial_value">32767</param>
-		</generator>
-	</id>
-
-	<property name="version" access="field" column="version" type="int"/>
-	<property name="creationDate" column="creationdate" type="timestamp" />
-	<property name="lastModified" column="lastmodified" type="timestamp" />
-	<property name="lastUserModified" column="lastusermodified" type="timestamp" />
-	<property name="lastCoachModified" column="lastcoachmodified" type="timestamp" />
-
-	<property name="score" column="score" type="float" />
-	<property name="passed" column="passed" type="boolean" />
-	<property name="totalNodes" column="total_nodes" type="int" />
-	<property name="attemptedNodes" column="attempted_nodes" type="int" />
-	<property name="passedNodes" column="passed_nodes" type="int" />
-
-	<property name="title" column="course_title" length="255"  type="string" />
-	<property name="shortTitle" column="course_short_title" length="128"  type="string" />
-	<property name="courseRepoKey" column="course_repo_key" type="long" />
-	<property name="statementXml" column="statement_xml" type="string" length="16777210" />
-	
-	<many-to-one name="resource"
-                 column="fk_resource_id"
-                 foreign-key="none"
-                 class="org.olat.resource.OLATResourceImpl"
-                 outer-join="true"
-                 unique="false"
-                 not-found="ignore"
-                 cascade="none"/>
-                 
-	<many-to-one name="identity"
-                 column="fk_identity"
-                 foreign-key="cx_eff_statement_to_identity"
-                 class="org.olat.basesecurity.IdentityImpl"
-                 outer-join="true"
-                 unique="false"
-                 cascade="none"/>
-  </class>
-  
-  <class name="org.olat.course.assessment.model.UserEfficiencyStatementStandalone" table="o_as_eff_statement">
-
-	<id name="key" type="long" column="id"	unsaved-value="null">
-		<generator class="enhanced-sequence">
-			<param name="sequence_name">hibernate_unique_key</param>
-			<param name="force_table_use">true</param>
-			<param name="optimizer">legacy-hilo</param>
-			<param name="value_column">next_hi</param>
-			<param name="increment_size">32767</param>
-			<param name="initial_value">32767</param>
-		</generator>
-	</id>
-
-	<property name="version" access="field" column="version" type="int"/>
-	<property name="creationDate" column="creationdate" type="timestamp" />
-	<property name="lastModified" column="lastmodified" type="timestamp" />
-	<property name="lastUserModified" column="lastusermodified" type="timestamp" />
-	<property name="lastCoachModified" column="lastcoachmodified" type="timestamp" />
-
-	<property name="score" column="score" type="float" />
-	<property name="passed" column="passed" type="boolean" />
-	<property name="totalNodes" column="total_nodes" type="int" />
-	<property name="attemptedNodes" column="attempted_nodes" type="int" />
-	<property name="passedNodes" column="passed_nodes" type="int" />
-
-	<property name="title" column="course_title" length="255"  type="string" />
-	<property name="shortTitle" column="course_short_title" length="128"  type="string" />
-	<property name="courseRepoKey" column="course_repo_key" type="long" />
-	<property name="statementXml" column="statement_xml" type="string" length="16777210" />
-	
-	<property name="resourceKey" column="fk_resource_id" type="long" />
-                 
-	<many-to-one name="identity"
-                 column="fk_identity"
-                 foreign-key="cx_eff_statement_to_identity"
-                 class="org.olat.basesecurity.IdentityImpl"
-                 outer-join="true"
-                 unique="false"
-                 cascade="none"/>
-  </class>
-  
-  <class name="org.olat.course.assessment.model.UserEfficiencyStatementLight" table="o_as_eff_statement" mutable="false">
-	<id name="key" type="long" column="id"	unsaved-value="null">
-		<generator class="enhanced-sequence">
-			<param name="sequence_name">hibernate_unique_key</param>
-			<param name="force_table_use">true</param>
-			<param name="optimizer">legacy-hilo</param>
-			<param name="value_column">next_hi</param>
-			<param name="increment_size">32767</param>
-			<param name="initial_value">32767</param>
-		</generator>
-	</id>
-
-	<property name="version" access="field" column="version" type="int"/>
-	<property name="creationDate" column="creationdate" type="timestamp" />
-	<property name="lastModified" column="lastmodified" type="timestamp" />
-	<property name="lastUserModified" column="lastusermodified" type="timestamp" />
-	<property name="lastCoachModified" column="lastcoachmodified" type="timestamp" />
-
-	<property name="score" column="score" type="float" />
-	<property name="passed" column="passed" type="boolean" />
-	<property name="totalNodes" column="total_nodes" type="int" />
-	<property name="attemptedNodes" column="attempted_nodes" type="int" />
-	<property name="passedNodes" column="passed_nodes" type="int" />
-	
-	<property name="shortTitle" column="course_short_title" type="string" />
-	<property name="courseRepoKey" column="course_repo_key" type="long" />
-	<property name="archivedResourceKey" column="fk_resource_id" type="long" insert="false" update="false" />
-
-	<many-to-one name="resource"
-                 column="fk_resource_id"
-                 foreign-key="none"
-                 class="org.olat.resource.OLATResourceImpl"
-                 outer-join="true"
-                 unique="false"
-                 not-found="ignore"
-                 cascade="none"/>
-                 
-	<many-to-one name="identity"
-                 column="fk_identity"
-                 foreign-key="cx_eff_statement_to_identity"
-                 class="org.olat.basesecurity.IdentityImpl"
-                 outer-join="true"
-                 unique="false"
-                 cascade="none"/>
-  </class>
-  
-</hibernate-mapping>
\ No newline at end of file
diff --git a/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementImpl.java b/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementImpl.java
index 2b4838673ec..28dcb17821c 100644
--- a/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementImpl.java
+++ b/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementImpl.java
@@ -21,42 +21,119 @@ package org.olat.course.assessment.model;
 
 import java.util.Date;
 
-import org.olat.core.commons.persistence.PersistentObject;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+import javax.persistence.Version;
+
+import org.hibernate.annotations.GenericGenerator;
+import org.hibernate.annotations.NotFound;
+import org.hibernate.annotations.NotFoundAction;
+import org.hibernate.annotations.Parameter;
+import org.olat.basesecurity.IdentityImpl;
 import org.olat.core.id.Identity;
 import org.olat.core.id.ModifiedInfo;
+import org.olat.core.id.Persistable;
 import org.olat.course.assessment.UserEfficiencyStatement;
 import org.olat.resource.OLATResource;
+import org.olat.resource.OLATResourceImpl;
 
 /**
  * 
  * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
  */
-public class UserEfficiencyStatementImpl extends PersistentObject implements UserEfficiencyStatement, ModifiedInfo {
+@Entity(name="effstatement")
+@Table(name="o_as_eff_statement")
+public class UserEfficiencyStatementImpl implements Persistable, UserEfficiencyStatement, ModifiedInfo {
 
 	private static final long serialVersionUID = 2996458434418813284L;
 	
+	@Id
+	@GeneratedValue(generator = "system-uuid")
+	@GenericGenerator(name = "system-uuid", strategy = "enhanced-sequence", parameters={
+		@Parameter(name="sequence_name", value="hibernate_unique_key"),
+		@Parameter(name="force_table_use", value="true"),
+		@Parameter(name="optimizer", value="legacy-hilo"),
+		@Parameter(name="value_column", value="next_hi"),
+		@Parameter(name="increment_size", value="32767"),
+		@Parameter(name="initial_value", value="32767")
+	})
+	@Column(name="id", nullable=false, unique=true, insertable=true, updatable=false)
+	private Long key;
+	@Version
+	private int version = 0;
+
+	@Temporal(TemporalType.TIMESTAMP)
+	@Column(name="creationdate", nullable=false, insertable=true, updatable=false)
+	private Date creationDate;
+	@Temporal(TemporalType.TIMESTAMP)
+	@Column(name="lastmodified", nullable=false, insertable=true, updatable=true)
+	private Date lastModified;
+
+	@Column(name="score", nullable=true, insertable=true, updatable=true)
 	private Float score;
+	@Column(name="passed", nullable=true, insertable=true, updatable=true)
 	private Boolean passed;
+	@Column(name="total_nodes", nullable=true, insertable=true, updatable=true)
 	private Integer totalNodes;
+	@Column(name="attempted_nodes", nullable=true, insertable=true, updatable=true)
 	private Integer attemptedNodes;
+	@Column(name="passed_nodes", nullable=true, insertable=true, updatable=true)
 	private Integer passedNodes;
-	
-	private Identity identity;
-	private OLATResource resource;
-	
+
+	@Column(name="course_title", nullable=true, insertable=true, updatable=true)
 	private String title;
+	@Column(name="course_short_title", nullable=true, insertable=true, updatable=true)
 	private String shortTitle;
+	@Column(name="course_repo_key", nullable=true, insertable=true, updatable=true)
 	private Long courseRepoKey;
-	
+
+	@Column(name="statement_xml", nullable=true, insertable=true, updatable=true)
 	private String statementXml;
-	
-	private Date lastModified;
+
+	@Temporal(TemporalType.TIMESTAMP)
+	@Column(name="lastusermodified", nullable=true, insertable=true, updatable=true)
 	private Date lastUserModified;
+	@Temporal(TemporalType.TIMESTAMP)
+	@Column(name="lastcoachmodified", nullable=true, insertable=true, updatable=true)
 	private Date lastCoachModified;
+
+	@ManyToOne(targetEntity=IdentityImpl.class,fetch=FetchType.LAZY,optional=false)
+	@JoinColumn(name="fk_identity", nullable=false, updatable=false)
+	private Identity identity;
+	@NotFound(action=NotFoundAction.IGNORE)
+	@ManyToOne(targetEntity=OLATResourceImpl.class,fetch=FetchType.EAGER,optional=true)
+	@JoinColumn(name="fk_resource_id", nullable=true, updatable=true)
+	private OLATResource resource;
 	
 	public UserEfficiencyStatementImpl() {
 		//
 	}
+	
+	@Override
+	public Long getKey() {
+		return key;
+	}
+	
+	public void setKey(Long key) {
+		this.key = key;
+	}
+
+	@Override
+	public Date getCreationDate() {
+		return creationDate;
+	}
+
+	public void setCreationDate(Date creationDate) {
+		this.creationDate = creationDate;
+	}
 
 	@Override
 	public Date getLastModified() {
@@ -201,4 +278,9 @@ public class UserEfficiencyStatementImpl extends PersistentObject implements Use
 		}
 		return false;
 	}
+
+	@Override
+	public boolean equalsByPersistableKey(Persistable persistable) {
+		return equals(persistable);
+	}
 }
diff --git a/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementLight.java b/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementLight.java
index f256aacf073..18cbaca1101 100644
--- a/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementLight.java
+++ b/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementLight.java
@@ -21,11 +21,29 @@ package org.olat.course.assessment.model;
 
 import java.util.Date;
 
-import org.olat.core.commons.persistence.PersistentObject;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+import javax.persistence.Version;
+
+import org.hibernate.annotations.GenericGenerator;
+import org.hibernate.annotations.NotFound;
+import org.hibernate.annotations.NotFoundAction;
+import org.hibernate.annotations.Parameter;
+import org.olat.basesecurity.IdentityImpl;
 import org.olat.core.id.Identity;
 import org.olat.core.id.ModifiedInfo;
+import org.olat.core.id.Persistable;
 import org.olat.course.assessment.UserEfficiencyStatement;
 import org.olat.resource.OLATResource;
+import org.olat.resource.OLATResourceImpl;
 
 /**
  * Description:
@@ -35,27 +53,85 @@ import org.olat.resource.OLATResource;
  * 
  * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
  */
-public class UserEfficiencyStatementLight extends PersistentObject implements UserEfficiencyStatement, ModifiedInfo {
+@Entity(name="effstatementlight")
+@Table(name="o_as_eff_statement")
+public class UserEfficiencyStatementLight implements Persistable, UserEfficiencyStatement, ModifiedInfo {
 
 	private static final long serialVersionUID = 2996458434418813284L;
 	
+	@Id
+	@GeneratedValue(generator = "system-uuid")
+	@GenericGenerator(name = "system-uuid", strategy = "enhanced-sequence", parameters={
+		@Parameter(name="sequence_name", value="hibernate_unique_key"),
+		@Parameter(name="force_table_use", value="true"),
+		@Parameter(name="optimizer", value="legacy-hilo"),
+		@Parameter(name="value_column", value="next_hi"),
+		@Parameter(name="increment_size", value="32767"),
+		@Parameter(name="initial_value", value="32767")
+	})
+	@Column(name="id", nullable=false, unique=true, insertable=true, updatable=false)
+	private Long key;
+	@Version
+	private int version = 0;
+
+	@Temporal(TemporalType.TIMESTAMP)
+	@Column(name="creationdate", nullable=false, insertable=true, updatable=false)
+	private Date creationDate;
+	@Temporal(TemporalType.TIMESTAMP)
+	@Column(name="lastmodified", nullable=false, insertable=true, updatable=true)
+	private Date lastModified;
+
+	@Column(name="score", nullable=true, insertable=true, updatable=true)
 	private Float score;
+	@Column(name="passed", nullable=true, insertable=true, updatable=true)
 	private Boolean passed;
+	@Column(name="total_nodes", nullable=true, insertable=true, updatable=true)
 	private Integer totalNodes;
+	@Column(name="attempted_nodes", nullable=true, insertable=true, updatable=true)
 	private Integer attemptedNodes;
+	@Column(name="passed_nodes", nullable=true, insertable=true, updatable=true)
 	private Integer passedNodes;
-	
-	private Identity identity;
-	private OLATResource resource;
 
+	@Column(name="course_short_title", nullable=true, insertable=true, updatable=true)
 	private String shortTitle;
+	@Column(name="course_repo_key", nullable=true, insertable=true, updatable=true)
 	private Long courseRepoKey;
+	@Column(name="fk_resource_id", nullable=true, insertable=false, updatable=false)
 	private Long archivedResourceKey;
-	
-	private Date lastModified;
+
+	@Temporal(TemporalType.TIMESTAMP)
+	@Column(name="lastusermodified", nullable=true, insertable=true, updatable=true)
 	private Date lastUserModified;
+	@Temporal(TemporalType.TIMESTAMP)
+	@Column(name="lastcoachmodified", nullable=true, insertable=true, updatable=true)
 	private Date lastCoachModified;
 
+	@ManyToOne(targetEntity=IdentityImpl.class,fetch=FetchType.LAZY,optional=false)
+	@JoinColumn(name="fk_identity", nullable=false, updatable=false)
+	private Identity identity;
+	@NotFound(action=NotFoundAction.IGNORE)
+	@ManyToOne(targetEntity=OLATResourceImpl.class,fetch=FetchType.EAGER,optional=true)
+	@JoinColumn(name="fk_resource_id", nullable=true, updatable=true)
+	private OLATResource resource;
+
+	@Override
+	public Long getKey() {
+		return key;
+	}
+	
+	public void setKey(Long key) {
+		this.key = key;
+	}
+
+	@Override
+	public Date getCreationDate() {
+		return creationDate;
+	}
+
+	public void setCreationDate(Date creationDate) {
+		this.creationDate = creationDate;
+	}
+
 	@Override	
 	public Date getLastModified() {
 		return lastModified;
@@ -191,4 +267,9 @@ public class UserEfficiencyStatementLight extends PersistentObject implements Us
 		}
 		return false;
 	}
+
+	@Override
+	public boolean equalsByPersistableKey(Persistable persistable) {
+		return equals(persistable);
+	}
 }
diff --git a/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementRepoImpl.java b/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementRepoImpl.java
deleted file mode 100644
index 01d46ed2151..00000000000
--- a/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementRepoImpl.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/**
- * <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.course.assessment.model;
-
-import java.util.Date;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.FetchType;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Id;
-import javax.persistence.JoinColumn;
-import javax.persistence.ManyToOne;
-import javax.persistence.Table;
-import javax.persistence.Temporal;
-import javax.persistence.TemporalType;
-
-import org.hibernate.annotations.GenericGenerator;
-import org.hibernate.annotations.Parameter;
-import org.olat.basesecurity.IdentityImpl;
-import org.olat.core.id.Identity;
-import org.olat.core.id.ModifiedInfo;
-import org.olat.core.id.Persistable;
-import org.olat.repository.RepositoryEntry;
-
-/**
- * 
- * Initial date: 07.10.2015<br>
- * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
- *
- */
-@Entity(name="effstatementrepo")
-@Table(name="o_as_eff_statement")
-public class UserEfficiencyStatementRepoImpl implements Persistable, ModifiedInfo {
-
-	private static final long serialVersionUID = 2996458434418813284L;
-	
-	@Id
-	@GeneratedValue(generator = "system-uuid")
-	@GenericGenerator(name = "system-uuid", strategy = "enhanced-sequence", parameters={
-		@Parameter(name="sequence_name", value="hibernate_unique_key"),
-		@Parameter(name="force_table_use", value="true"),
-		@Parameter(name="optimizer", value="legacy-hilo"),
-		@Parameter(name="value_column", value="next_hi"),
-		@Parameter(name="increment_size", value="32767"),
-		@Parameter(name="initial_value", value="32767")
-	})
-	@Column(name="id", nullable=false, unique=true, insertable=true, updatable=false)
-	private Long key;
-
-	@Temporal(TemporalType.TIMESTAMP)
-	@Column(name="creationdate", nullable=false, insertable=true, updatable=false)
-	private Date creationDate;
-	@Temporal(TemporalType.TIMESTAMP)
-	@Column(name="lastmodified", nullable=false, insertable=true, updatable=true)
-	private Date lastModified;
-	
-	@Column(name="score", nullable=true, insertable=true, updatable=true)
-	private Float score;
-	@Column(name="passed", nullable=true, insertable=true, updatable=true)
-	private Boolean passed;
-	@Column(name="total_nodes", nullable=true, insertable=true, updatable=true)
-	private Integer totalNodes;
-	@Column(name="attempted_nodes", nullable=true, insertable=true, updatable=true)
-	private Integer attemptedNodes;
-	@Column(name="passed_nodes", nullable=true, insertable=true, updatable=true)
-	private Integer passedNodes;
-
-	@Column(name="course_title", nullable=true, insertable=true, updatable=true)
-	private String title;
-	@Column(name="course_short_title", nullable=true, insertable=true, updatable=true)
-	private String shortTitle;
-	
-	@ManyToOne(targetEntity=RepositoryEntry.class,fetch=FetchType.LAZY,optional=false)
-	@JoinColumn(name="course_repo_key", nullable=false, updatable=false)
-	private RepositoryEntry repositoryEntry;
-	
-	@ManyToOne(targetEntity=IdentityImpl.class,fetch=FetchType.LAZY,optional=false)
-	@JoinColumn(name="fk_identity", nullable=false, updatable=false)
-	private Identity identity;
-	
-	
-	@Override
-	public Long getKey() {
-		return key;
-	}
-
-	@Override
-	public Date getLastModified() {
-		return lastModified;
-	}
-
-	@Override
-	public void setLastModified(Date lastModified) {
-		this.lastModified = lastModified;
-	}
-
-	public Float getScore() {
-		return score;
-	}
-		
-	public void setScore(Float score) {
-		this.score = score;
-	}
-
-	public Boolean getPassed() {
-		return passed;
-	}
-		
-	public void setPassed(Boolean passed) {
-		this.passed = passed;
-	}
-
-	public Integer getTotalNodes() {
-		return totalNodes;
-	}
-
-	public void setTotalNodes(Integer totalNodes) {
-		this.totalNodes = totalNodes;
-	}
-
-	public Integer getAttemptedNodes() {
-		return attemptedNodes;
-	}
-
-	public void setAttemptedNodes(Integer attemptedNodes) {
-		this.attemptedNodes = attemptedNodes;
-	}
-
-	public Integer getPassedNodes() {
-		return passedNodes;
-	}
-
-	public void setPassedNodes(Integer passedNodes) {
-		this.passedNodes = passedNodes;
-	}
-
-	public Identity getIdentity() {
-		return identity;
-	}
-	
-	public void setIdentity(Identity identity) {
-		this.identity = identity;
-	}
-	
-	public String getTitle() {
-		return title;
-	}
-
-	public void setTitle(String title) {
-		this.title = title;
-	}
-
-	public String getShortTitle() {
-		return shortTitle;
-	}
-
-	public void setShortTitle(String shortTitle) {
-		this.shortTitle = shortTitle;
-	}
-
-	@Override
-	public String toString() {
-		return super.toString();
-	}
-	
-	@Override
-	public int hashCode() {
-		return getKey() == null ? -82654 : getKey().hashCode();
-	}
-	
-	@Override
-	public boolean equals(Object obj) {
-		if(this == obj) {
-			return true;
-		}
-		if(obj instanceof UserEfficiencyStatementRepoImpl) {
-			UserEfficiencyStatementRepoImpl statement = (UserEfficiencyStatementRepoImpl)obj;
-			return getKey() != null && getKey().equals(statement.getKey());
-		}
-		return false;
-	}
-
-	@Override
-	public boolean equalsByPersistableKey(Persistable persistable) {
-		return equals(persistable);
-	}
-}
diff --git a/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementStandalone.java b/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementStandalone.java
index 3effbfee696..cd3209117ca 100644
--- a/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementStandalone.java
+++ b/src/main/java/org/olat/course/assessment/model/UserEfficiencyStatementStandalone.java
@@ -21,9 +21,24 @@ package org.olat.course.assessment.model;
 
 import java.util.Date;
 
-import org.olat.core.commons.persistence.PersistentObject;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+import javax.persistence.Version;
+
+import org.hibernate.annotations.GenericGenerator;
+import org.hibernate.annotations.Parameter;
+import org.olat.basesecurity.IdentityImpl;
 import org.olat.core.id.Identity;
 import org.olat.core.id.ModifiedInfo;
+import org.olat.core.id.Persistable;
 import org.olat.course.assessment.UserEfficiencyStatement;
 
 /**
@@ -33,28 +48,85 @@ import org.olat.course.assessment.UserEfficiencyStatement;
  * 
  * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
  */
-public class UserEfficiencyStatementStandalone extends PersistentObject implements UserEfficiencyStatement, ModifiedInfo {
+@Entity(name="effstatementstandalone")
+@Table(name="o_as_eff_statement")
+public class UserEfficiencyStatementStandalone implements Persistable, UserEfficiencyStatement, ModifiedInfo {
 
 	private static final long serialVersionUID = 2996458434418813284L;
 	
+	@Id
+	@GeneratedValue(generator = "system-uuid")
+	@GenericGenerator(name = "system-uuid", strategy = "enhanced-sequence", parameters={
+		@Parameter(name="sequence_name", value="hibernate_unique_key"),
+		@Parameter(name="force_table_use", value="true"),
+		@Parameter(name="optimizer", value="legacy-hilo"),
+		@Parameter(name="value_column", value="next_hi"),
+		@Parameter(name="increment_size", value="32767"),
+		@Parameter(name="initial_value", value="32767")
+	})
+	@Column(name="id", nullable=false, unique=true, insertable=true, updatable=false)
+	private Long key;
+	@Version
+	private int version = 0;
+
+	@Temporal(TemporalType.TIMESTAMP)
+	@Column(name="creationdate", nullable=false, insertable=true, updatable=false)
+	private Date creationDate;
+	@Temporal(TemporalType.TIMESTAMP)
+	@Column(name="lastmodified", nullable=false, insertable=true, updatable=true)
+	private Date lastModified;
+
+	@Column(name="score", nullable=true, insertable=true, updatable=true)
 	private Float score;
+	@Column(name="passed", nullable=true, insertable=true, updatable=true)
 	private Boolean passed;
+	@Column(name="total_nodes", nullable=true, insertable=true, updatable=true)
 	private Integer totalNodes;
+	@Column(name="attempted_nodes", nullable=true, insertable=true, updatable=true)
 	private Integer attemptedNodes;
+	@Column(name="passed_nodes", nullable=true, insertable=true, updatable=true)
 	private Integer passedNodes;
 	
-	private Identity identity;
-	private Long resourceKey;
-	
+	@Column(name="course_title", nullable=true, insertable=true, updatable=true)
 	private String title;
+	@Column(name="course_short_title", nullable=true, insertable=true, updatable=true)
 	private String shortTitle;
+	@Column(name="course_repo_key", nullable=true, insertable=true, updatable=true)
 	private Long courseRepoKey;
-	
+
+	@Column(name="statement_xml", nullable=true, insertable=true, updatable=true)
 	private String statementXml;
-	
-	private Date lastModified;
+
+	@Temporal(TemporalType.TIMESTAMP)
+	@Column(name="lastusermodified", nullable=true, insertable=true, updatable=true)
 	private Date lastUserModified;
+	@Temporal(TemporalType.TIMESTAMP)
+	@Column(name="lastcoachmodified", nullable=true, insertable=true, updatable=true)
 	private Date lastCoachModified;
+
+	@ManyToOne(targetEntity=IdentityImpl.class,fetch=FetchType.LAZY,optional=false)
+	@JoinColumn(name="fk_identity", nullable=false, updatable=false)
+	private Identity identity;
+	@Column(name="fk_resource_id", nullable=true, insertable=true, updatable=true)
+	private Long resourceKey;
+	
+	@Override
+	public Long getKey() {
+		return key;
+	}
+	
+	public void setKey(Long key) {
+		this.key = key;
+	}
+
+	@Override
+	public Date getCreationDate() {
+		return creationDate;
+	}
+
+	public void setCreationDate(Date creationDate) {
+		this.creationDate = creationDate;
+	}
 	
 	@Override
 	public Date getLastModified() {
@@ -197,4 +269,9 @@ public class UserEfficiencyStatementStandalone extends PersistentObject implemen
 		}
 		return false;
 	}
+
+	@Override
+	public boolean equalsByPersistableKey(Persistable persistable) {
+		return equals(persistable);
+	}
 }
diff --git a/src/main/resources/META-INF/persistence.xml b/src/main/resources/META-INF/persistence.xml
index d8c1ed921d3..9a89ffe0075 100644
--- a/src/main/resources/META-INF/persistence.xml
+++ b/src/main/resources/META-INF/persistence.xml
@@ -5,8 +5,8 @@
         http://java.sun.com/xml/ns/persistence
         http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
 	<persistence-unit name="default">
-		<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
-
+		<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> 
+		
 		<mapping-file>de/bps/olat/modules/cl/Checklist.hbm.xml</mapping-file>
 		<mapping-file>de/bps/olat/modules/cl/CheckpointResult.hbm.xml</mapping-file>
 		<mapping-file>de/bps/olat/modules/cl/Checkpoint.hbm.xml</mapping-file>
@@ -28,7 +28,6 @@
 		<mapping-file>org/olat/repository/model/CatalogEntryImpl.hbm.xml</mapping-file>
 		<mapping-file>org/olat/course/nodes/projectbroker/datamodel/Project.hbm.xml</mapping-file>
 		<mapping-file>org/olat/course/nodes/projectbroker/datamodel/ProjectBroker.hbm.xml</mapping-file>
-		<mapping-file>org/olat/course/assessment/model/UserEfficiencyStatementImpl.hbm.xml</mapping-file>
 		<mapping-file>org/olat/modules/openmeetings/model/OpenMeetingsReference.hbm.xml</mapping-file>
 		<mapping-file>org/olat/properties/Property.hbm.xml</mapping-file>
 		<mapping-file>org/olat/portfolio/model/artefacts/AbstractArtefact.hbm.xml</mapping-file>
@@ -93,7 +92,9 @@
 		<class>org.olat.course.assessment.model.AssessmentModeToGroupImpl</class>
 		<class>org.olat.course.assessment.model.AssessmentModeToCurriculumElementImpl</class>
 		<class>org.olat.course.assessment.model.UserCourseInfosImpl</class>
-		<class>org.olat.course.assessment.model.UserEfficiencyStatementRepoImpl</class>
+		<class>org.olat.course.assessment.model.UserEfficiencyStatementImpl</class>
+		<class>org.olat.course.assessment.model.UserEfficiencyStatementLight</class>
+		<class>org.olat.course.assessment.model.UserEfficiencyStatementStandalone</class>
 		<class>org.olat.course.nodes.cl.model.DBCheckbox</class>
 		<class>org.olat.course.nodes.cl.model.DBCheck</class>
 		<class>org.olat.course.nodes.dialog.model.DialogElementImpl</class>
@@ -249,6 +250,8 @@
 		<class>org.olat.shibboleth.manager.ShibbolethAutoAccessMethod</class>
 		<class>org.olat.user.UserImpl</class>
 		<class>org.olat.user.model.UserDataExportImpl</class>
+		
+		<exclude-unlisted-classes>true</exclude-unlisted-classes>
 		<properties>
 			<property name="hibernate.generate_statistics" value="true"/>
 			<property name="hibernate.archive.autodetection" value=""/>
diff --git a/src/test/java/org/olat/course/assessment/manager/EfficiencyStatementManagerTest.java b/src/test/java/org/olat/course/assessment/manager/EfficiencyStatementManagerTest.java
index 149b87286d7..e12aba70ca2 100644
--- a/src/test/java/org/olat/course/assessment/manager/EfficiencyStatementManagerTest.java
+++ b/src/test/java/org/olat/course/assessment/manager/EfficiencyStatementManagerTest.java
@@ -32,7 +32,9 @@ import org.olat.core.commons.persistence.DB;
 import org.olat.core.id.Identity;
 import org.olat.course.CourseFactory;
 import org.olat.course.ICourse;
+import org.olat.course.assessment.EfficiencyStatement;
 import org.olat.course.assessment.UserEfficiencyStatement;
+import org.olat.course.assessment.model.UserEfficiencyStatementImpl;
 import org.olat.course.assessment.model.UserEfficiencyStatementLight;
 import org.olat.modules.coach.CoachingLargeTest;
 import org.olat.repository.RepositoryEntry;
@@ -62,7 +64,7 @@ public class EfficiencyStatementManagerTest extends OlatTestCase {
 	 * @throws URISyntaxException
 	 */
 	@Test
-	public void testEfficiencyStatement() throws URISyntaxException {
+	public void createEfficiencyStatement() throws URISyntaxException {
 		RepositoryEntry re = deployTestcourse();
 		ICourse course = CourseFactory.loadCourse(re);
 		
@@ -93,6 +95,376 @@ public class EfficiencyStatementManagerTest extends OlatTestCase {
 		Assert.assertEquals(6.0f, statementLight.getScore(), 0.00001);
 	}
 	
+	@Test
+	public void getUserEfficiencyStatementLightByKey() throws URISyntaxException {
+		RepositoryEntry re = deployTestcourse();
+		ICourse course = CourseFactory.loadCourse(re);
+		
+		//add some members
+		Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("Eff-Part-4");
+		repositoryService.addRole(participant, re, GroupRoles.participant.name());
+		dbInstance.commitAndCloseSession();
+
+		//make statements
+	    UserEfficiencyStatement statement = effManager.createUserEfficiencyStatement(new Date(), 4.5f, false, participant, re.getOlatResource());
+		dbInstance.commitAndCloseSession();
+		
+		UserEfficiencyStatementLight reloadedStatement = effManager.getUserEfficiencyStatementLightByKey(statement.getKey());
+		Assert.assertNotNull(reloadedStatement);
+		Assert.assertEquals(statement.getKey(), reloadedStatement.getKey());
+		Assert.assertEquals(participant, reloadedStatement.getIdentity());
+		Assert.assertEquals(re.getKey(), reloadedStatement.getCourseRepoKey());
+		Assert.assertEquals(course.getCourseTitle(), reloadedStatement.getShortTitle());
+		Assert.assertEquals(re.getOlatResource(), reloadedStatement.getResource());
+		Assert.assertEquals(re.getOlatResource().getKey(), reloadedStatement.getArchivedResourceKey());
+		Assert.assertNotNull(reloadedStatement.getCreationDate());
+		Assert.assertNotNull(reloadedStatement.getLastModified());
+		Assert.assertFalse(reloadedStatement.getPassed());
+		Assert.assertEquals(4.5f, reloadedStatement.getScore(), 0.00001);
+	}
+	
+	@Test
+	public void getUserEfficiencyStatementByKey() throws URISyntaxException {
+		RepositoryEntry re = deployTestcourse();
+		ICourse course = CourseFactory.loadCourse(re);
+		
+		//add some members
+		Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("Eff-Part-5");
+		repositoryService.addRole(participant, re, GroupRoles.participant.name());
+		dbInstance.commitAndCloseSession();
+
+		//make statements
+	    UserEfficiencyStatement statement = effManager.createUserEfficiencyStatement(new Date(), 4.5f, false, participant, re.getOlatResource());
+		dbInstance.commitAndCloseSession();
+		effManager.updateEfficiencyStatements(re, Collections.singletonList(participant));
+		
+		EfficiencyStatement effStatement = effManager.getUserEfficiencyStatementByKey(statement.getKey());
+		Assert.assertNotNull(effStatement);
+		Assert.assertEquals(course.getCourseTitle(), effStatement.getCourseTitle());
+		Assert.assertEquals(re.getKey(), effStatement.getCourseRepoEntryKey());
+	}
+	
+	@Test
+	public void getUserEfficiencyStatementFull() throws URISyntaxException {
+		RepositoryEntry re = deployTestcourse();
+		ICourse course = CourseFactory.loadCourse(re);
+		
+		//add some members
+		Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("Eff-Part-5");
+		repositoryService.addRole(participant, re, GroupRoles.participant.name());
+		dbInstance.commitAndCloseSession();
+
+		//make statements
+	    UserEfficiencyStatement statement = effManager.createUserEfficiencyStatement(new Date(), 3.75f, false, participant, re.getOlatResource());
+		dbInstance.commitAndCloseSession();
+		
+		UserEfficiencyStatementImpl fullStatement = effManager.getUserEfficiencyStatementFull(re, participant);
+		Assert.assertNotNull(fullStatement);
+		Assert.assertEquals(statement.getKey(), fullStatement.getKey());
+		Assert.assertEquals(participant, fullStatement.getIdentity());
+		Assert.assertEquals(re.getKey(), fullStatement.getCourseRepoKey());
+		Assert.assertEquals(course.getCourseTitle(), fullStatement.getShortTitle());
+		Assert.assertEquals(re.getOlatResource(), fullStatement.getResource());
+		Assert.assertNotNull(fullStatement.getCreationDate());
+		Assert.assertNotNull(fullStatement.getLastModified());
+		Assert.assertFalse(fullStatement.getPassed());
+		Assert.assertEquals(3.75f, fullStatement.getScore(), 0.00001);
+	}
+	
+	@Test
+	public void getUserEfficiencyStatementLightByRepositoryEntry() throws URISyntaxException {
+		RepositoryEntry re = deployTestcourse();
+		ICourse course = CourseFactory.loadCourse(re);
+		
+		//add some members
+		Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("Eff-Part-5");
+		repositoryService.addRole(participant, re, GroupRoles.participant.name());
+		dbInstance.commitAndCloseSession();
+
+		//make statements
+	    UserEfficiencyStatement statement = effManager.createUserEfficiencyStatement(new Date(), 3.75f, false, participant, re.getOlatResource());
+		dbInstance.commitAndCloseSession();
+		
+		UserEfficiencyStatement lightStatement = effManager.getUserEfficiencyStatementLightByRepositoryEntry(re, participant);
+		Assert.assertNotNull(lightStatement);
+		Assert.assertEquals(statement.getKey(), lightStatement.getKey());
+		Assert.assertEquals(participant, lightStatement.getIdentity());
+		Assert.assertEquals(re.getKey(), lightStatement.getCourseRepoKey());
+		Assert.assertEquals(course.getCourseTitle(), lightStatement.getShortTitle());
+		Assert.assertNotNull(lightStatement.getCreationDate());
+		Assert.assertNotNull(lightStatement.getLastModified());
+		Assert.assertFalse(lightStatement.getPassed());
+		Assert.assertEquals(3.75f, lightStatement.getScore(), 0.00001);
+	}
+	
+	@Test
+	public void getUserEfficiencyStatementLight_identityRepo() throws URISyntaxException {
+		RepositoryEntry re = deployTestcourse();
+		ICourse course = CourseFactory.loadCourse(re);
+		
+		//add some members
+		Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("Eff-Part-5");
+		repositoryService.addRole(participant, re, GroupRoles.participant.name());
+		dbInstance.commitAndCloseSession();
+
+		//make statements
+	    UserEfficiencyStatement statement = effManager.createUserEfficiencyStatement(new Date(), 3.75f, false, participant, re.getOlatResource());
+		dbInstance.commitAndCloseSession();
+		
+		List<UserEfficiencyStatement> lightStatements = effManager.getUserEfficiencyStatementLight(participant, Collections.singletonList(re));
+		Assert.assertNotNull(lightStatements);
+		Assert.assertEquals(1, lightStatements.size());
+		UserEfficiencyStatement lightStatement = lightStatements.get(0);
+		Assert.assertNotNull(lightStatement);
+		Assert.assertEquals(statement.getKey(), lightStatement.getKey());
+		Assert.assertEquals(participant, lightStatement.getIdentity());
+		Assert.assertEquals(re.getKey(), lightStatement.getCourseRepoKey());
+		Assert.assertEquals(course.getCourseTitle(), lightStatement.getShortTitle());
+		Assert.assertNotNull(lightStatement.getCreationDate());
+		Assert.assertNotNull(lightStatement.getLastModified());
+		Assert.assertFalse(lightStatement.getPassed());
+		Assert.assertEquals(3.75f, lightStatement.getScore(), 0.00001);
+	}
+	
+	@Test
+	public void getUserEfficiencyStatementLight_identity() throws URISyntaxException {
+		RepositoryEntry re = deployTestcourse();
+		
+		//add some members
+		Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("Eff-Part-6");
+		repositoryService.addRole(participant, re, GroupRoles.participant.name());
+		dbInstance.commitAndCloseSession();
+
+		//make statements
+	    UserEfficiencyStatement statement = effManager.createUserEfficiencyStatement(new Date(), 3.75f, false, participant, re.getOlatResource());
+		dbInstance.commitAndCloseSession();
+		
+		List<UserEfficiencyStatement> lightStatements = effManager.getUserEfficiencyStatementLight(participant);
+		Assert.assertNotNull(lightStatements);
+		Assert.assertEquals(1, lightStatements.size());
+		UserEfficiencyStatement lightStatement = lightStatements.get(0);
+		Assert.assertNotNull(lightStatement);
+		Assert.assertEquals(statement.getKey(), lightStatement.getKey());
+		Assert.assertEquals(participant, lightStatement.getIdentity());
+		Assert.assertEquals(re.getKey(), lightStatement.getCourseRepoKey());
+	}
+	
+	@Test
+	public void getUserEfficiencyStatementLight_repo() throws URISyntaxException {
+		RepositoryEntry re = deployTestcourse();
+		
+		//add some members
+		Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("Eff-Part-7");
+		repositoryService.addRole(participant, re, GroupRoles.participant.name());
+		dbInstance.commitAndCloseSession();
+
+		//make statements
+	    UserEfficiencyStatement statement = effManager.createUserEfficiencyStatement(new Date(), 3.75f, false, participant, re.getOlatResource());
+		dbInstance.commitAndCloseSession();
+		
+		List<UserEfficiencyStatement> lightStatements = effManager.getUserEfficiencyStatementLight(re);
+		Assert.assertNotNull(lightStatements);
+		Assert.assertEquals(1, lightStatements.size());
+		UserEfficiencyStatement lightStatement = lightStatements.get(0);
+		Assert.assertNotNull(lightStatement);
+		Assert.assertEquals(statement.getKey(), lightStatement.getKey());
+		Assert.assertEquals(participant, lightStatement.getIdentity());
+		Assert.assertEquals(re.getKey(), lightStatement.getCourseRepoKey());
+	}
+	
+	@Test
+	public void getUserEfficiencyStatementLight_repos() throws URISyntaxException {
+		RepositoryEntry re = deployTestcourse();
+		
+		//add some members
+		Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("Eff-Part-7");
+		repositoryService.addRole(participant, re, GroupRoles.participant.name());
+		dbInstance.commitAndCloseSession();
+
+		//make statements
+	    UserEfficiencyStatement statement = effManager.createUserEfficiencyStatement(new Date(), 3.75f, false, participant, re.getOlatResource());
+		dbInstance.commitAndCloseSession();
+		
+		List<UserEfficiencyStatement> lightStatements = effManager.getUserEfficiencyStatementLight(Collections.singletonList(re));
+		Assert.assertNotNull(lightStatements);
+		Assert.assertEquals(1, lightStatements.size());
+		UserEfficiencyStatement lightStatement = lightStatements.get(0);
+		Assert.assertNotNull(lightStatement);
+		Assert.assertEquals(statement.getKey(), lightStatement.getKey());
+		Assert.assertEquals(participant, lightStatement.getIdentity());
+		Assert.assertEquals(re.getKey(), lightStatement.getCourseRepoKey());
+	}
+	
+	@Test
+	public void getUserEfficiencyStatementLightByResource() throws URISyntaxException {
+		RepositoryEntry re = deployTestcourse();
+		
+		//add some members
+		Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("Eff-Part-7");
+		repositoryService.addRole(participant, re, GroupRoles.participant.name());
+		dbInstance.commitAndCloseSession();
+
+		//make statements
+	    UserEfficiencyStatement statement = effManager.createUserEfficiencyStatement(new Date(), 3.75f, false, participant, re.getOlatResource());
+		dbInstance.commitAndCloseSession();
+		
+		UserEfficiencyStatement lightStatement = effManager.getUserEfficiencyStatementLightByResource(re.getOlatResource().getKey(), participant);
+		Assert.assertNotNull(lightStatement);
+		Assert.assertEquals(statement.getKey(), lightStatement.getKey());
+		Assert.assertEquals(participant, lightStatement.getIdentity());
+		Assert.assertEquals(re.getKey(), lightStatement.getCourseRepoKey());
+	}
+	
+	@Test
+	public void getUserEfficiencyStatementLightByResource_standalone() throws URISyntaxException {
+		Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("Eff-Part-7");
+		dbInstance.commitAndCloseSession();
+		
+		Long resourceKey = 725l;
+
+		//make statements
+	    UserEfficiencyStatement statement = effManager.createStandAloneUserEfficiencyStatement(new Date(), 22.0f, Boolean.TRUE, participant, resourceKey, "Hello");
+		dbInstance.commitAndCloseSession();
+		
+		UserEfficiencyStatement lightStatement = effManager.getUserEfficiencyStatementLightByResource(resourceKey, participant);
+		Assert.assertNotNull(lightStatement);
+		Assert.assertEquals(statement.getKey(), lightStatement.getKey());
+		Assert.assertEquals(participant, lightStatement.getIdentity());
+		Assert.assertNull(lightStatement.getCourseRepoKey());
+		Assert.assertEquals("Hello", lightStatement.getShortTitle());
+		Assert.assertTrue(lightStatement.getPassed());
+		Assert.assertEquals(22.0f, lightStatement.getScore(), 0.00001);
+	}
+	
+	@Test
+	public void findEfficiencyStatements() throws URISyntaxException {
+		RepositoryEntry re = deployTestcourse();
+		ICourse course = CourseFactory.loadCourse(re);
+		
+		//add some members
+		Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("Eff-Part-5");
+		repositoryService.addRole(participant, re, GroupRoles.participant.name());
+		dbInstance.commitAndCloseSession();
+		
+		//make statements
+	    UserEfficiencyStatement statement = effManager.createUserEfficiencyStatement(new Date(), 4.5f, false, participant, re.getOlatResource());
+		dbInstance.commitAndCloseSession();
+		effManager.updateEfficiencyStatements(re, Collections.singletonList(participant));
+			
+		List<EfficiencyStatement> effStatements = effManager.findEfficiencyStatements(participant);
+		Assert.assertNotNull(effStatements);
+		Assert.assertEquals(1, effStatements.size());
+		EfficiencyStatement effStatement = effStatements.get(0);
+		Assert.assertNotNull(effStatement);
+		Assert.assertEquals(course.getCourseTitle(), effStatement.getCourseTitle());
+		Assert.assertEquals(re.getKey(), effStatement.getCourseRepoEntryKey());
+		Assert.assertEquals(statement.getCourseRepoKey(), effStatement.getCourseRepoEntryKey());
+	}
+	
+	@Test
+	public void findEfficiencyStatementsLight_standalone() {
+		Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("Eff-Part-9");
+		dbInstance.commitAndCloseSession();
+		
+		Long resourceKey = 725l;
+
+		//make statements
+	    UserEfficiencyStatement statement = effManager.createStandAloneUserEfficiencyStatement(new Date(), 22.0f, Boolean.TRUE, participant, resourceKey, "Hello");
+		dbInstance.commitAndCloseSession();
+		
+		List<UserEfficiencyStatementLight> lightStatements = effManager.findEfficiencyStatementsLight(participant);
+		Assert.assertNotNull(lightStatements);
+		Assert.assertEquals(1, lightStatements.size());
+		UserEfficiencyStatementLight lightStatement = lightStatements.get(0);
+		Assert.assertNotNull(lightStatement);
+		Assert.assertEquals(statement.getKey(), lightStatement.getKey());
+		Assert.assertEquals(participant, lightStatement.getIdentity());
+		Assert.assertNull(lightStatement.getCourseRepoKey());
+		Assert.assertEquals("Hello", lightStatement.getShortTitle());
+		Assert.assertTrue(lightStatement.getPassed());
+		Assert.assertEquals(22.0f, lightStatement.getScore(), 0.00001);
+	}
+	
+	@Test
+	public void findEfficiencyStatementsLight_identity() throws URISyntaxException {
+		RepositoryEntry re = deployTestcourse();
+		ICourse course = CourseFactory.loadCourse(re);
+		
+		//add some members
+		Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("Eff-Part-5");
+		repositoryService.addRole(participant, re, GroupRoles.participant.name());
+		dbInstance.commitAndCloseSession();
+		
+		//make statements
+	    UserEfficiencyStatement statement = effManager.createUserEfficiencyStatement(new Date(), 102.3f, true, participant, re.getOlatResource());
+		dbInstance.commitAndCloseSession();
+		// this will reset score to 0 and passed to false
+		effManager.updateEfficiencyStatements(re, Collections.singletonList(participant));
+		
+		List<UserEfficiencyStatementLight> lightStatements = effManager.findEfficiencyStatementsLight(participant);
+		Assert.assertNotNull(lightStatements);
+		Assert.assertEquals(1, lightStatements.size());
+		UserEfficiencyStatementLight lightStatement = lightStatements.get(0);
+		Assert.assertNotNull(lightStatement);
+		Assert.assertEquals(statement.getKey(), lightStatement.getKey());
+		Assert.assertEquals(participant, lightStatement.getIdentity());
+		Assert.assertEquals(re.getKey(), lightStatement.getCourseRepoKey());
+		Assert.assertEquals(course.getCourseTitle(), lightStatement.getShortTitle());
+		Assert.assertFalse(lightStatement.getPassed());
+		Assert.assertEquals(0f, lightStatement.getScore(), 0.00001);
+	}
+	
+	@Test
+	public void findEfficiencyStatementsLight_statementKeys() throws URISyntaxException {
+		RepositoryEntry re = deployTestcourse();
+		ICourse course = CourseFactory.loadCourse(re);
+		
+		//add some members
+		Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("Eff-Part-5");
+		repositoryService.addRole(participant, re, GroupRoles.participant.name());
+		dbInstance.commitAndCloseSession();
+		
+		//make statements
+	    UserEfficiencyStatement statement = effManager.createUserEfficiencyStatement(new Date(), 102.3f, true, participant, re.getOlatResource());
+		dbInstance.commitAndCloseSession();
+		// this will reset score to 0 and passed to false
+		effManager.updateEfficiencyStatements(re, Collections.singletonList(participant));
+		
+		List<UserEfficiencyStatementLight> lightStatements = effManager
+				.findEfficiencyStatementsLight(Collections.singletonList(statement.getKey()));
+		Assert.assertNotNull(lightStatements);
+		Assert.assertEquals(1, lightStatements.size());
+		UserEfficiencyStatementLight lightStatement = lightStatements.get(0);
+		Assert.assertNotNull(lightStatement);
+		Assert.assertEquals(statement.getKey(), lightStatement.getKey());
+		Assert.assertEquals(participant, lightStatement.getIdentity());
+		Assert.assertEquals(re.getKey(), lightStatement.getCourseRepoKey());
+		Assert.assertEquals(course.getCourseTitle(), lightStatement.getShortTitle());
+		Assert.assertFalse(lightStatement.getPassed());
+		Assert.assertEquals(0f, lightStatement.getScore(), 0.00001);
+	}
+	
+	@Test
+	public void findIdentitiesWithEfficiencyStatements() throws URISyntaxException {
+		RepositoryEntry re = deployTestcourse();
+		
+		//add some members
+		Identity participant = JunitTestHelper.createAndPersistIdentityAsRndUser("Eff-Part-5");
+		repositoryService.addRole(participant, re, GroupRoles.participant.name());
+		dbInstance.commitAndCloseSession();
+		
+		//make statements
+	    UserEfficiencyStatement statement = effManager.createUserEfficiencyStatement(new Date(), 102.3f, true, participant, re.getOlatResource());
+		dbInstance.commitAndCloseSession();
+		// this will reset score to 0 and passed to false
+		effManager.updateEfficiencyStatements(re, Collections.singletonList(participant));
+		
+		List<Identity> assessedIdentities = effManager.findIdentitiesWithEfficiencyStatements(re.getKey());
+		Assert.assertNotNull(assessedIdentities);
+		Assert.assertEquals(1, assessedIdentities.size());
+		Assert.assertEquals(statement.getIdentity(), assessedIdentities.get(0));
+		Assert.assertEquals(participant, assessedIdentities.get(0));
+	}
 	
 	@Test
 	public void deleteUserData() throws URISyntaxException {
diff --git a/src/test/java/org/olat/restapi/EfficiencyStatementTest.java b/src/test/java/org/olat/restapi/EfficiencyStatementTest.java
index 6d2f6ed8a9b..4638a4f204d 100644
--- a/src/test/java/org/olat/restapi/EfficiencyStatementTest.java
+++ b/src/test/java/org/olat/restapi/EfficiencyStatementTest.java
@@ -25,6 +25,7 @@ import java.io.IOException;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.Date;
+import java.util.List;
 
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.UriBuilder;
@@ -123,7 +124,7 @@ public class EfficiencyStatementTest extends OlatJerseyTestCase {
 		EntityUtils.consume(response.getEntity());
 
 		UserEfficiencyStatement efficiencyStatement = efficiencyStatementManager
-				.getUserEfficiencyStatementFullByResourceKey(entry.getOlatResource().getKey(), assessedIdentity);
+				.getUserEfficiencyStatementFull(entry, assessedIdentity);
 
 		Assert.assertNotNull(efficiencyStatement);
 		Assert.assertNotNull(efficiencyStatement.getCourseRepoKey());
@@ -161,9 +162,12 @@ public class EfficiencyStatementTest extends OlatJerseyTestCase {
 		EntityUtils.consume(response.getEntity());
 
 		//check the efficiency statement
-		UserEfficiencyStatement efficiencyStatement = efficiencyStatementManager
-				.getUserEfficiencyStatementFullByResourceKey(resourceKey, assessedIdentity);
-		Assert.assertNotNull(efficiencyStatement);
+		List<UserEfficiencyStatement> efficiencyStatements = efficiencyStatementManager
+				.getUserEfficiencyStatementLight(assessedIdentity);
+		Assert.assertNotNull(efficiencyStatements);
+		Assert.assertEquals(1, efficiencyStatements.size());
+		
+		UserEfficiencyStatement efficiencyStatement = efficiencyStatements.get(0);
 		Assert.assertEquals(8.5f, efficiencyStatement.getScore(), 0.001);
 		Assert.assertEquals(Boolean.TRUE, efficiencyStatement.getPassed());
 		Assert.assertEquals("Standalone", efficiencyStatement.getShortTitle());
@@ -205,9 +209,12 @@ public class EfficiencyStatementTest extends OlatJerseyTestCase {
 		EntityUtils.consume(response.getEntity());
 
 		//check the efficiency statement
-		UserEfficiencyStatement efficiencyStatement = efficiencyStatementManager
-				.getUserEfficiencyStatementFullByResourceKey(resourceKey, assessedIdentity);
-		Assert.assertNotNull(efficiencyStatement);
+		List<UserEfficiencyStatement> efficiencyStatements = efficiencyStatementManager
+				.getUserEfficiencyStatementLight(assessedIdentity);
+		Assert.assertNotNull(efficiencyStatements);
+		Assert.assertEquals(1, efficiencyStatements.size());
+		
+		UserEfficiencyStatement efficiencyStatement = efficiencyStatements.get(0);
 		Assert.assertEquals(8.5f, efficiencyStatement.getScore(), 0.001);
 		Assert.assertEquals(Boolean.TRUE, efficiencyStatement.getPassed());
 		Assert.assertEquals("Standalone", efficiencyStatement.getShortTitle());
-- 
GitLab