Remove notifications from queue when associated project or task deleted
Prevents a HibernateObjectRetrievalFailureException from being thrown when a scheduled email notification job attempts to send a notification associated to a project or task that was deleted prior to the scheduled job running. Fixes #4
This commit is contained in:
parent
2b1a91a9f6
commit
b101d18e9e
7 changed files with 144 additions and 1 deletions
|
|
@ -23,8 +23,12 @@ import org.hibernate.criterion.Restrictions;
|
||||||
import org.libreplan.business.common.daos.GenericDAOHibernate;
|
import org.libreplan.business.common.daos.GenericDAOHibernate;
|
||||||
import org.libreplan.business.email.entities.EmailNotification;
|
import org.libreplan.business.email.entities.EmailNotification;
|
||||||
import org.libreplan.business.email.entities.EmailTemplateEnum;
|
import org.libreplan.business.email.entities.EmailTemplateEnum;
|
||||||
|
import org.libreplan.business.orders.entities.Order;
|
||||||
|
import org.libreplan.business.planner.entities.TaskElement;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
//import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -50,6 +54,22 @@ public class EmailNotificationDAO
|
||||||
.list();
|
.list();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<EmailNotification> getAllByProject(TaskElement taskElement) {
|
||||||
|
return getSession()
|
||||||
|
.createCriteria(EmailNotification.class)
|
||||||
|
.add(Restrictions.eq("project", taskElement))
|
||||||
|
.list();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<EmailNotification> getAllByTask(TaskElement taskElement) {
|
||||||
|
return getSession()
|
||||||
|
.createCriteria(EmailNotification.class)
|
||||||
|
.add(Restrictions.eq("task", taskElement))
|
||||||
|
.list();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean deleteAll() {
|
public boolean deleteAll() {
|
||||||
List<EmailNotification> notifications = list(EmailNotification.class);
|
List<EmailNotification> notifications = list(EmailNotification.class);
|
||||||
|
|
@ -89,4 +109,26 @@ public class EmailNotificationDAO
|
||||||
.uniqueResult() == null;
|
.uniqueResult() == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean deleteByProject(TaskElement taskElement) {
|
||||||
|
List<EmailNotification> notifications = getAllByProject(taskElement);
|
||||||
|
|
||||||
|
for (Object item : notifications){
|
||||||
|
getSession().delete(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return getAllByProject(taskElement).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean deleteByTask(TaskElement taskElement) {
|
||||||
|
List<EmailNotification> notifications = getAllByTask(taskElement);
|
||||||
|
|
||||||
|
for (Object item : notifications){
|
||||||
|
getSession().delete(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
return getAllByTask(taskElement).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,8 @@ package org.libreplan.business.email.daos;
|
||||||
import org.libreplan.business.common.daos.IGenericDAO;
|
import org.libreplan.business.common.daos.IGenericDAO;
|
||||||
import org.libreplan.business.email.entities.EmailNotification;
|
import org.libreplan.business.email.entities.EmailNotification;
|
||||||
import org.libreplan.business.email.entities.EmailTemplateEnum;
|
import org.libreplan.business.email.entities.EmailTemplateEnum;
|
||||||
|
import org.libreplan.business.orders.entities.Order;
|
||||||
|
import org.libreplan.business.planner.entities.TaskElement;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
@ -36,9 +38,18 @@ public interface IEmailNotificationDAO extends IGenericDAO<EmailNotification, Lo
|
||||||
|
|
||||||
List<EmailNotification> getAllByType(EmailTemplateEnum enumeration);
|
List<EmailNotification> getAllByType(EmailTemplateEnum enumeration);
|
||||||
|
|
||||||
|
List<EmailNotification> getAllByProject(TaskElement taskElement);
|
||||||
|
|
||||||
|
List<EmailNotification> getAllByTask(TaskElement taskElement);
|
||||||
|
|
||||||
boolean deleteAll();
|
boolean deleteAll();
|
||||||
|
|
||||||
boolean deleteAllByType(EmailTemplateEnum enumeration);
|
boolean deleteAllByType(EmailTemplateEnum enumeration);
|
||||||
|
|
||||||
boolean deleteById(EmailNotification notification);
|
boolean deleteById(EmailNotification notification);
|
||||||
|
|
||||||
|
boolean deleteByProject(TaskElement taskElement);
|
||||||
|
|
||||||
|
boolean deleteByTask(TaskElement taskElement);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ import org.hibernate.Query;
|
||||||
import org.hibernate.criterion.Restrictions;
|
import org.hibernate.criterion.Restrictions;
|
||||||
import org.libreplan.business.common.daos.IntegrationEntityDAO;
|
import org.libreplan.business.common.daos.IntegrationEntityDAO;
|
||||||
import org.libreplan.business.common.exceptions.InstanceNotFoundException;
|
import org.libreplan.business.common.exceptions.InstanceNotFoundException;
|
||||||
|
import org.libreplan.business.email.daos.IEmailNotificationDAO;
|
||||||
import org.libreplan.business.expensesheet.daos.IExpenseSheetLineDAO;
|
import org.libreplan.business.expensesheet.daos.IExpenseSheetLineDAO;
|
||||||
import org.libreplan.business.labels.entities.Label;
|
import org.libreplan.business.labels.entities.Label;
|
||||||
import org.libreplan.business.orders.entities.Order;
|
import org.libreplan.business.orders.entities.Order;
|
||||||
|
|
@ -46,6 +47,7 @@ import org.libreplan.business.orders.entities.OrderElement;
|
||||||
import org.libreplan.business.orders.entities.SchedulingDataForVersion;
|
import org.libreplan.business.orders.entities.SchedulingDataForVersion;
|
||||||
import org.libreplan.business.orders.entities.TaskSource;
|
import org.libreplan.business.orders.entities.TaskSource;
|
||||||
import org.libreplan.business.planner.daos.ITaskSourceDAO;
|
import org.libreplan.business.planner.daos.ITaskSourceDAO;
|
||||||
|
import org.libreplan.business.planner.entities.TaskElement;
|
||||||
import org.libreplan.business.resources.entities.Criterion;
|
import org.libreplan.business.resources.entities.Criterion;
|
||||||
import org.libreplan.business.templates.entities.OrderElementTemplate;
|
import org.libreplan.business.templates.entities.OrderElementTemplate;
|
||||||
import org.libreplan.business.workingday.EffortDuration;
|
import org.libreplan.business.workingday.EffortDuration;
|
||||||
|
|
@ -84,6 +86,9 @@ public class OrderElementDAO extends IntegrationEntityDAO<OrderElement> implemen
|
||||||
@Autowired
|
@Autowired
|
||||||
private ITaskSourceDAO taskSourceDAO;
|
private ITaskSourceDAO taskSourceDAO;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IEmailNotificationDAO emailNotificationDAO;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<OrderElement> findWithoutParent() {
|
public List<OrderElement> findWithoutParent() {
|
||||||
return getSession()
|
return getSession()
|
||||||
|
|
@ -142,6 +147,9 @@ public class OrderElementDAO extends IntegrationEntityDAO<OrderElement> implemen
|
||||||
@Override
|
@Override
|
||||||
public void remove(Long id) throws InstanceNotFoundException {
|
public void remove(Long id) throws InstanceNotFoundException {
|
||||||
OrderElement orderElement = find(id);
|
OrderElement orderElement = find(id);
|
||||||
|
|
||||||
|
removeNotifications(orderElement);
|
||||||
|
|
||||||
removeTaskSourcesFor(this.taskSourceDAO, orderElement);
|
removeTaskSourcesFor(this.taskSourceDAO, orderElement);
|
||||||
|
|
||||||
for (WorkReport each : getWorkReportsPointingTo(orderElement)) {
|
for (WorkReport each : getWorkReportsPointingTo(orderElement)) {
|
||||||
|
|
@ -151,6 +159,17 @@ public class OrderElementDAO extends IntegrationEntityDAO<OrderElement> implemen
|
||||||
super.remove(id);
|
super.remove(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void removeNotifications(OrderElement orderElement) {
|
||||||
|
|
||||||
|
List<SchedulingDataForVersion> allVersions = orderElement.getSchedulingDataForVersionFromBottomToTop();
|
||||||
|
for (TaskSource each : taskSourcesFrom(allVersions)) {
|
||||||
|
TaskElement taskElement = each.getTask();
|
||||||
|
if ( taskElement != null) {
|
||||||
|
emailNotificationDAO.deleteByTask(taskElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void removeTaskSourcesFor(ITaskSourceDAO taskSourceDAO, OrderElement orderElement)
|
public static void removeTaskSourcesFor(ITaskSourceDAO taskSourceDAO, OrderElement orderElement)
|
||||||
throws InstanceNotFoundException {
|
throws InstanceNotFoundException {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ package org.libreplan.web.email;
|
||||||
import org.libreplan.business.common.exceptions.ValidationException;
|
import org.libreplan.business.common.exceptions.ValidationException;
|
||||||
import org.libreplan.business.email.daos.IEmailNotificationDAO;
|
import org.libreplan.business.email.daos.IEmailNotificationDAO;
|
||||||
import org.libreplan.business.email.entities.EmailTemplateEnum;
|
import org.libreplan.business.email.entities.EmailTemplateEnum;
|
||||||
|
import org.libreplan.business.orders.entities.Order;
|
||||||
import org.libreplan.business.email.entities.EmailNotification;
|
import org.libreplan.business.email.entities.EmailNotification;
|
||||||
|
|
||||||
import org.libreplan.business.planner.entities.TaskElement;
|
import org.libreplan.business.planner.entities.TaskElement;
|
||||||
|
|
@ -68,6 +69,17 @@ public class EmailNotificationModel implements IEmailNotificationModel {
|
||||||
return emailNotificationDAO.getAllByType(enumeration);
|
return emailNotificationDAO.getAllByType(enumeration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public List<EmailNotification> getAllByProject(TaskElement taskElement) {
|
||||||
|
return emailNotificationDAO.getAllByProject(taskElement);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public List<EmailNotification> getAllByTask(TaskElement taskElement) {
|
||||||
|
return emailNotificationDAO.getAllByTask(taskElement);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public boolean deleteAll() {
|
public boolean deleteAll() {
|
||||||
|
|
@ -85,6 +97,18 @@ public class EmailNotificationModel implements IEmailNotificationModel {
|
||||||
return emailNotificationDAO.deleteById(notification);
|
return emailNotificationDAO.deleteById(notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public boolean deleteByProject(TaskElement taskElement) {
|
||||||
|
return emailNotificationDAO.deleteByProject(taskElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public boolean deleteByTask(TaskElement taskElement) {
|
||||||
|
return emailNotificationDAO.deleteByTask(taskElement);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setType(EmailTemplateEnum type) {
|
public void setType(EmailTemplateEnum type) {
|
||||||
this.emailNotification.setType(type);
|
this.emailNotification.setType(type);
|
||||||
|
|
@ -110,11 +134,12 @@ public class EmailNotificationModel implements IEmailNotificationModel {
|
||||||
this.emailNotification.setProject(project);
|
this.emailNotification.setProject(project);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public EmailNotification getEmailNotification() {
|
public EmailNotification getEmailNotification() {
|
||||||
return emailNotification;
|
return emailNotification;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setNewObject(){
|
public void setNewObject(){
|
||||||
this.emailNotification = new EmailNotification();
|
this.emailNotification = new EmailNotification();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ package org.libreplan.web.email;
|
||||||
|
|
||||||
import org.libreplan.business.common.exceptions.ValidationException;
|
import org.libreplan.business.common.exceptions.ValidationException;
|
||||||
import org.libreplan.business.email.entities.EmailTemplateEnum;
|
import org.libreplan.business.email.entities.EmailTemplateEnum;
|
||||||
|
import org.libreplan.business.orders.entities.Order;
|
||||||
import org.libreplan.business.email.entities.EmailNotification;
|
import org.libreplan.business.email.entities.EmailNotification;
|
||||||
import org.libreplan.business.planner.entities.TaskElement;
|
import org.libreplan.business.planner.entities.TaskElement;
|
||||||
import org.libreplan.business.resources.entities.Resource;
|
import org.libreplan.business.resources.entities.Resource;
|
||||||
|
|
@ -41,12 +42,20 @@ public interface IEmailNotificationModel {
|
||||||
|
|
||||||
List<EmailNotification> getAllByType(EmailTemplateEnum enumeration);
|
List<EmailNotification> getAllByType(EmailTemplateEnum enumeration);
|
||||||
|
|
||||||
|
List<EmailNotification> getAllByProject(TaskElement taskElement);
|
||||||
|
|
||||||
|
List<EmailNotification> getAllByTask(TaskElement taskElement);
|
||||||
|
|
||||||
boolean deleteAll();
|
boolean deleteAll();
|
||||||
|
|
||||||
boolean deleteAllByType(EmailTemplateEnum enumeration);
|
boolean deleteAllByType(EmailTemplateEnum enumeration);
|
||||||
|
|
||||||
boolean deleteById(EmailNotification notification);
|
boolean deleteById(EmailNotification notification);
|
||||||
|
|
||||||
|
boolean deleteByProject(TaskElement taskElement);
|
||||||
|
|
||||||
|
boolean deleteByTask(TaskElement taskElement);
|
||||||
|
|
||||||
void setType(EmailTemplateEnum type);
|
void setType(EmailTemplateEnum type);
|
||||||
|
|
||||||
void setUpdated(Date date);
|
void setUpdated(Date date);
|
||||||
|
|
@ -60,4 +69,5 @@ public interface IEmailNotificationModel {
|
||||||
EmailNotification getEmailNotification();
|
EmailNotification getEmailNotification();
|
||||||
|
|
||||||
void setNewObject();
|
void setNewObject();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ import org.libreplan.business.common.daos.IConfigurationDAO;
|
||||||
import org.libreplan.business.common.entities.Configuration;
|
import org.libreplan.business.common.entities.Configuration;
|
||||||
import org.libreplan.business.common.entities.EntityNameEnum;
|
import org.libreplan.business.common.entities.EntityNameEnum;
|
||||||
import org.libreplan.business.common.exceptions.InstanceNotFoundException;
|
import org.libreplan.business.common.exceptions.InstanceNotFoundException;
|
||||||
|
import org.libreplan.business.email.entities.EmailNotification;
|
||||||
import org.libreplan.business.externalcompanies.daos.IExternalCompanyDAO;
|
import org.libreplan.business.externalcompanies.daos.IExternalCompanyDAO;
|
||||||
import org.libreplan.business.externalcompanies.entities.EndDateCommunication;
|
import org.libreplan.business.externalcompanies.entities.EndDateCommunication;
|
||||||
import org.libreplan.business.externalcompanies.entities.ExternalCompany;
|
import org.libreplan.business.externalcompanies.entities.ExternalCompany;
|
||||||
|
|
@ -60,6 +61,7 @@ import org.libreplan.business.orders.entities.OrderElement;
|
||||||
import org.libreplan.business.orders.entities.OrderLineGroup;
|
import org.libreplan.business.orders.entities.OrderLineGroup;
|
||||||
import org.libreplan.business.orders.entities.OrderStatusEnum;
|
import org.libreplan.business.orders.entities.OrderStatusEnum;
|
||||||
import org.libreplan.business.planner.entities.PositionConstraintType;
|
import org.libreplan.business.planner.entities.PositionConstraintType;
|
||||||
|
import org.libreplan.business.planner.entities.TaskElement;
|
||||||
import org.libreplan.business.qualityforms.daos.IQualityFormDAO;
|
import org.libreplan.business.qualityforms.daos.IQualityFormDAO;
|
||||||
import org.libreplan.business.qualityforms.entities.QualityForm;
|
import org.libreplan.business.qualityforms.entities.QualityForm;
|
||||||
import org.libreplan.business.requirements.entities.DirectCriterionRequirement;
|
import org.libreplan.business.requirements.entities.DirectCriterionRequirement;
|
||||||
|
|
@ -84,6 +86,7 @@ import org.libreplan.business.users.entities.UserRole;
|
||||||
import org.libreplan.web.calendars.BaseCalendarModel;
|
import org.libreplan.web.calendars.BaseCalendarModel;
|
||||||
import org.libreplan.web.common.IntegrationEntityModel;
|
import org.libreplan.web.common.IntegrationEntityModel;
|
||||||
import org.libreplan.web.common.concurrentdetection.OnConcurrentModification;
|
import org.libreplan.web.common.concurrentdetection.OnConcurrentModification;
|
||||||
|
import org.libreplan.web.email.IEmailNotificationModel;
|
||||||
import org.libreplan.web.logs.IIssueLogModel;
|
import org.libreplan.web.logs.IIssueLogModel;
|
||||||
import org.libreplan.web.logs.IRiskLogModel;
|
import org.libreplan.web.logs.IRiskLogModel;
|
||||||
import org.libreplan.web.orders.files.IOrderFileModel;
|
import org.libreplan.web.orders.files.IOrderFileModel;
|
||||||
|
|
@ -181,6 +184,9 @@ public class OrderModel extends IntegrationEntityModel implements IOrderModel {
|
||||||
@Autowired
|
@Autowired
|
||||||
private IIssueLogModel issueLogModel;
|
private IIssueLogModel issueLogModel;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IEmailNotificationModel emailNotificationModel;
|
||||||
|
|
||||||
private List<Order> orderList = new ArrayList<>();
|
private List<Order> orderList = new ArrayList<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -522,6 +528,8 @@ public class OrderModel extends IntegrationEntityModel implements IOrderModel {
|
||||||
public void remove(Order detachedOrder) {
|
public void remove(Order detachedOrder) {
|
||||||
Order order = orderDAO.findExistingEntity(detachedOrder.getId());
|
Order order = orderDAO.findExistingEntity(detachedOrder.getId());
|
||||||
|
|
||||||
|
removeNotifications(order);
|
||||||
|
|
||||||
removeFiles(order);
|
removeFiles(order);
|
||||||
|
|
||||||
removeLogs(order);
|
removeLogs(order);
|
||||||
|
|
@ -542,6 +550,18 @@ public class OrderModel extends IntegrationEntityModel implements IOrderModel {
|
||||||
orderFileModel.findByParent(order).forEach(orderFile -> orderFileModel.delete(orderFile));
|
orderFileModel.findByParent(order).forEach(orderFile -> orderFileModel.delete(orderFile));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void removeNotifications(Order order) {
|
||||||
|
|
||||||
|
for ( Scenario scenario: currentAndDerivedScenarios()) {
|
||||||
|
order.useSchedulingDataFor(scenario.getOrderVersion(order));
|
||||||
|
|
||||||
|
TaskElement taskElement = order.getTaskElement();
|
||||||
|
if ( taskElement != null) {
|
||||||
|
emailNotificationModel.deleteByProject(taskElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void removeVersions(Order order) {
|
private void removeVersions(Order order) {
|
||||||
Map<Long, OrderVersion> versionsRemovedById = new HashMap<>();
|
Map<Long, OrderVersion> versionsRemovedById = new HashMap<>();
|
||||||
List<Scenario> currentAndDerived = currentAndDerivedScenarios();
|
List<Scenario> currentAndDerived = currentAndDerivedScenarios();
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,9 @@ package org.libreplan.web.test.ws.email;
|
||||||
|
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.ExpectedException;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
import org.libreplan.business.common.Registry;
|
import org.libreplan.business.common.Registry;
|
||||||
|
|
@ -167,6 +169,20 @@ public class EmailTest {
|
||||||
assertTrue(EmailConnectionValidator.exceptionType instanceof MessagingException);
|
assertTrue(EmailConnectionValidator.exceptionType instanceof MessagingException);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Transactional
|
||||||
|
public void testDDeleteEmailNotification() {
|
||||||
|
EmailTemplate emailTemplate = createEmailTemplate();
|
||||||
|
emailTemplateDAO.save(emailTemplate);
|
||||||
|
|
||||||
|
EmailNotification emailNotification = createEmailNotification();
|
||||||
|
emailNotificationDAO.save(emailNotification);
|
||||||
|
|
||||||
|
emailTemplateDAO.delete(emailTemplate);
|
||||||
|
boolean result = emailNotificationDAO.deleteByProject(emailNotification.getProject());
|
||||||
|
assertTrue(result);
|
||||||
|
}
|
||||||
|
|
||||||
private EmailTemplate createEmailTemplate() {
|
private EmailTemplate createEmailTemplate() {
|
||||||
EmailTemplate emailTemplate = new EmailTemplate();
|
EmailTemplate emailTemplate = new EmailTemplate();
|
||||||
emailTemplate.setType(EmailTemplateEnum.TEMPLATE_TODAY_TASK_SHOULD_START);
|
emailTemplate.setType(EmailTemplateEnum.TEMPLATE_TODAY_TASK_SHOULD_START);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue