diff --git a/src/main/java/org/olat/modules/qpool/manager/QuestionItemDAO.java b/src/main/java/org/olat/modules/qpool/manager/QuestionItemDAO.java index 18f2a2b4e58b44df635a86c11ccdbf2f3b730bdd..cffa62aed082255927eab4bcd97bd074530075aa 100644 --- a/src/main/java/org/olat/modules/qpool/manager/QuestionItemDAO.java +++ b/src/main/java/org/olat/modules/qpool/manager/QuestionItemDAO.java @@ -36,6 +36,8 @@ import org.olat.basesecurity.SecurityGroupMembershipImpl; import org.olat.core.commons.persistence.DB; import org.olat.core.commons.services.mark.impl.MarkImpl; import org.olat.core.id.Identity; +import org.olat.core.logging.OLog; +import org.olat.core.logging.Tracing; import org.olat.core.util.StringHelper; import org.olat.group.BusinessGroup; import org.olat.modules.qpool.QuestionItem; @@ -60,6 +62,8 @@ import org.springframework.stereotype.Service; @Service("questionDao") public class QuestionItemDAO { + private static final OLog log = Tracing.createLoggerFor(QuestionItemDAO.class); + @Autowired private DB dbInstance; @Autowired @@ -222,14 +226,42 @@ public class QuestionItemDAO { return query.getResultList(); } - public void delete(List<QuestionItemShort> items) { + public void delete(List<? extends QuestionItemShort> items) { EntityManager em = dbInstance.getCurrentEntityManager(); for(QuestionItemShort item:items) { - QuestionItem refItem = em.getReference(QuestionItemImpl.class, item.getKey()); - em.remove(refItem); + QuestionItem refItem = loadLazyReferenceId(item.getKey()); + if(refItem != null) { + em.remove(refItem); + } } } + /** + * The method only load the question item and doesn't fetch + * anything. + * + * @param key The primary key of the item + * @return The question item or null if not found + */ + private QuestionItem loadLazyReferenceId(Long key) { + StringBuilder sb = new StringBuilder(); + sb.append("select item from questionitem item") + .append(" where item.key=:key"); + List<QuestionItem> items = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), QuestionItem.class) + .setParameter("key", key) + .getResultList(); + return items == null || items.isEmpty() ? null : items.get(0); + } + + /** + * The method loads the question item and fetch + * the taxonomy level, license, item type and + * educational context. + * + * @param key The primary key of the item + * @return The question item or null if not found + */ public QuestionItemImpl loadById(Long key) { StringBuilder sb = new StringBuilder(); sb.append("select item from questionitem item") diff --git a/src/test/java/org/olat/modules/qpool/manager/QuestionDAOTest.java b/src/test/java/org/olat/modules/qpool/manager/QuestionDAOTest.java index 98da047d1a674868071d6889288e833eea07e525..48d592b18c8df0185df4beec1d4f5d3a6127ee7a 100644 --- a/src/test/java/org/olat/modules/qpool/manager/QuestionDAOTest.java +++ b/src/test/java/org/olat/modules/qpool/manager/QuestionDAOTest.java @@ -20,6 +20,7 @@ package org.olat.modules.qpool.manager; import java.math.BigDecimal; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Locale; @@ -451,4 +452,41 @@ public class QuestionDAOTest extends OlatTestCase { Assert.assertEquals(1, count); dbInstance.commit();//make sure that changes are committed } + + @Test + public void deleteQuestion() { + QItemType fibType = qItemTypeDao.loadByType(QuestionType.FIB.name()); + QuestionItem item = questionDao.createAndPersist(null, "To delete 1", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, fibType); + dbInstance.commitAndCloseSession(); + + List<QuestionItem> itemsToDelete = Collections.singletonList(item); + questionDao.delete(itemsToDelete); + dbInstance.commitAndCloseSession(); + + QuestionItem deletedItem = questionDao.loadById(item.getKey()); + Assert.assertNull(deletedItem); + } + + @Test + public void deleteQuestion_alreadyDeletedQuestions() { + QItemType fibType = qItemTypeDao.loadByType(QuestionType.FIB.name()); + QuestionItem item1 = questionDao.createAndPersist(null, "To delete 1", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, fibType); + QuestionItem item2 = questionDao.createAndPersist(null, "To delete 2", QTIConstants.QTI_12_FORMAT, Locale.ENGLISH.getLanguage(), null, null, null, fibType); + dbInstance.commitAndCloseSession(); + + // delete item 1 + questionDao.delete(Collections.singletonList(item1)); + dbInstance.commitAndCloseSession(); + + List<QuestionItem> itemsToDelete = new ArrayList<>(); + itemsToDelete.add(item1); + itemsToDelete.add(item2); + questionDao.delete(itemsToDelete); + dbInstance.commitAndCloseSession(); + + QuestionItem deletedItem1 = questionDao.loadById(item1.getKey()); + Assert.assertNull(deletedItem1); + QuestionItem deletedItem2 = questionDao.loadById(item2.getKey()); + Assert.assertNull(deletedItem2); + } } \ No newline at end of file