From 4aab033b4712c4b6094e6d62656e5b4f0c5c1be6 Mon Sep 17 00:00:00 2001
From: srosse <none@none>
Date: Mon, 9 Nov 2015 09:16:51 +0100
Subject: [PATCH] OO-1774: use a delete statement for reservations instead of
 remove to prevent exception if the reservation was already deleted

---
 .../manager/ACReservationDAO.java             | 10 +--
 .../accesscontrol/ACReservationDAOTest.java   | 65 ++++++++++++++++++-
 2 files changed, 69 insertions(+), 6 deletions(-)

diff --git a/src/main/java/org/olat/resource/accesscontrol/manager/ACReservationDAO.java b/src/main/java/org/olat/resource/accesscontrol/manager/ACReservationDAO.java
index 3fe5f2d9e4f..6c978efdc80 100644
--- a/src/main/java/org/olat/resource/accesscontrol/manager/ACReservationDAO.java
+++ b/src/main/java/org/olat/resource/accesscontrol/manager/ACReservationDAO.java
@@ -22,7 +22,6 @@ package org.olat.resource.accesscontrol.manager;
 import java.util.Date;
 import java.util.List;
 
-import javax.persistence.EntityManager;
 import javax.persistence.TemporalType;
 
 import org.olat.core.commons.persistence.DB;
@@ -130,10 +129,11 @@ public class ACReservationDAO {
 		return count.intValue();
 	}
 	
-	public void deleteReservation(ResourceReservation reservation) {
-		EntityManager em = dbInstance.getCurrentEntityManager();
-		ResourceReservation reloaded = em.getReference(ResourceReservationImpl.class, reservation.getKey());
-		em.remove(reloaded);
+	public int deleteReservation(ResourceReservation reservation) {
+		String sb = "delete from resourcereservation as reservation where reservation.key=:reservationKey";
+		return dbInstance.getCurrentEntityManager().createQuery(sb)
+			.setParameter("reservationKey", reservation.getKey())
+			.executeUpdate();
 	}
 	
 	public void deleteReservations(OLATResource resource) {
diff --git a/src/test/java/org/olat/resource/accesscontrol/ACReservationDAOTest.java b/src/test/java/org/olat/resource/accesscontrol/ACReservationDAOTest.java
index 37d0f3e0ee7..bf48e3f15df 100644
--- a/src/test/java/org/olat/resource/accesscontrol/ACReservationDAOTest.java
+++ b/src/test/java/org/olat/resource/accesscontrol/ACReservationDAOTest.java
@@ -209,11 +209,74 @@ public class ACReservationDAOTest extends OlatTestCase  {
 		ResourceReservation deletedReservation = acReservationDao.loadReservation(reservation.getKey());
 		Assert.assertNull(deletedReservation);
 	}
+	
+	@Test
+	public void testDeleteReservation_entityNotFound() {
+		//create 3 identities and 3 reservations
+		Identity id = JunitTestHelper.createAndPersistIdentityAsUser("reserv-5-" + UUID.randomUUID().toString());
+		OLATResource resource = JunitTestHelper.createRandomResource();
+		ResourceReservation reservation = acReservationDao.createReservation(id, "test", null, resource);
+		dbInstance.commitAndCloseSession();
+		
+		//count reservations
+		int count = acReservationDao.countReservations(resource);
+		Assert.assertEquals(1, count);
+		
+		//delete reservation
+		int rowDeleted = acReservationDao.deleteReservation(reservation);
+		dbInstance.commitAndCloseSession();
+		Assert.assertEquals(1, rowDeleted);
+		
+		//try a second delete
+		int rowDeleted2 = acReservationDao.deleteReservation(reservation);
+		Assert.assertEquals(0, rowDeleted2);
+
+		int count2 = acReservationDao.countReservations(resource);
+		dbInstance.commitAndCloseSession();
+		Assert.assertEquals(0, count2);
+	}
+	
+	/**
+	 * check that one and only one reservation is deleted.
+	 */
+	@Test
+	public void testDeleteReservation_paranoiaCheck() {
+		//create 3 identities and 3 reservations
+		Identity id1 = JunitTestHelper.createAndPersistIdentityAsUser("reserv-6-" + UUID.randomUUID().toString());
+		Identity id2 = JunitTestHelper.createAndPersistIdentityAsUser("reserv-8-" + UUID.randomUUID().toString());
+		OLATResource resource1 = JunitTestHelper.createRandomResource();
+		OLATResource resource2 = JunitTestHelper.createRandomResource();
+		ResourceReservation reservation1_1 = acReservationDao.createReservation(id1, "test", null, resource1);
+		ResourceReservation reservation1_2 = acReservationDao.createReservation(id1, "test", null, resource2);
+		ResourceReservation reservation2_1 = acReservationDao.createReservation(id2, "test", null, resource1);
+		ResourceReservation reservation2_2 = acReservationDao.createReservation(id2, "test", null, resource2);
+		dbInstance.commitAndCloseSession();
+		Assert.assertNotNull(reservation1_1);
+		Assert.assertNotNull(reservation1_2);
+		Assert.assertNotNull(reservation2_1);
+		Assert.assertNotNull(reservation2_2);
+		
+		//count reservations
+		int count1 = acReservationDao.countReservations(resource1);
+		Assert.assertEquals(2, count1);
+		int count2 = acReservationDao.countReservations(resource2);
+		Assert.assertEquals(2, count2);
+		
+		//delete reservation identity 1 on resource 2
+		int rowDeleted = acReservationDao.deleteReservation(reservation1_2);
+		dbInstance.commitAndCloseSession();
+		Assert.assertEquals(1, rowDeleted);
+
+		int checkCount1 = acReservationDao.countReservations(resource1);
+		Assert.assertEquals(2, checkCount1);
+		int checkCount2 = acReservationDao.countReservations(resource2);
+		Assert.assertEquals(1, checkCount2);
+	}
 
 	@Test
 	public void testDeleteReservations() {
 		//create 3 identities and 3 reservations
-		Identity id = JunitTestHelper.createAndPersistIdentityAsUser("reserv-4-" + UUID.randomUUID().toString());
+		Identity id = JunitTestHelper.createAndPersistIdentityAsUser("reserv-7-" + UUID.randomUUID().toString());
 		OLATResource resource1 = JunitTestHelper.createRandomResource();
 		OLATResource resource2 = JunitTestHelper.createRandomResource();
 		ResourceReservation reservation1_1 = acReservationDao.createReservation(id, "test delete 1", null, resource1);
-- 
GitLab