diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/common/concurrentdetection/ConcurrentModificationHandling.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/concurrentdetection/ConcurrentModificationHandling.java
new file mode 100644
index 000000000..69174ccca
--- /dev/null
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/concurrentdetection/ConcurrentModificationHandling.java
@@ -0,0 +1,71 @@
+/*
+ * This file is part of NavalPlan
+ *
+ * Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
+ * Desenvolvemento Tecnolóxico de Galicia
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+package org.navalplanner.web.common.concurrentdetection;
+
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.core.annotation.Order;
+import org.springframework.dao.OptimisticLockingFailureException;
+
+/**
+ * Responsible of handling {@link OptimisticLockingFailureException} on Spring
+ * beans marked with {@link OnConcurrentModification}
+ * @author Óscar González Fernández
+ */
+@Aspect
+@Order(0)
+public class ConcurrentModificationHandling {
+
+ public ConcurrentModificationHandling() {
+ }
+
+ @SuppressWarnings("unused")
+ @Pointcut("@within(onConcurrentModification))")
+ private void methodWithinConcurrentModificationMarkedType(
+ OnConcurrentModification onConcurrentModification) {
+ }
+
+ /**
+ * It intercepts the calls to public methods of Spring beans marked with
+ * {@link OnConcurrentModification}. When an
+ * {@link OptimisticLockingFailureException} happens the page for concurrent
+ * modification is shown and the user is returned to the page specified by
+ * {@link OnConcurrentModification}
+ * @param jointPoint
+ * @param onConcurrentModification
+ * the annotation applied to object's type
+ * @return the object that would be originally returned
+ */
+ @Around("methodWithinConcurrentModificationMarkedType(onConcurrentModification)"
+ + " && execution(public * * (..))")
+ public Object whenConcurrentModification(ProceedingJoinPoint jointPoint,
+ OnConcurrentModification onConcurrentModification) throws Throwable {
+ try {
+ return jointPoint.proceed(jointPoint.getArgs());
+ } catch (OptimisticLockingFailureException e) {
+ ConcurrentModificationController.showException(e,
+ onConcurrentModification.goToPage());
+ throw e;
+ }
+ }
+}
diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/common/concurrentdetection/OnConcurrentModification.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/concurrentdetection/OnConcurrentModification.java
new file mode 100644
index 000000000..3093c03b3
--- /dev/null
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/concurrentdetection/OnConcurrentModification.java
@@ -0,0 +1,43 @@
+/*
+ * This file is part of NavalPlan
+ *
+ * Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
+ * Desenvolvemento Tecnolóxico de Galicia
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+package org.navalplanner.web.common.concurrentdetection;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.springframework.dao.OptimisticLockingFailureException;
+
+/**
+ * This annotation must be applied on spring beans that want to inform the user
+ * that an {@link OptimisticLockingFailureException} has happened. After showing
+ * it, the user can go back to the page supplied on this annotation
+ * @author Óscar González Fernández
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface OnConcurrentModification {
+
+ public String goToPage();
+
+}
diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/worker/WorkerModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/worker/WorkerModel.java
index 8ccb2293d..664c802bc 100644
--- a/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/worker/WorkerModel.java
+++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/resources/worker/WorkerModel.java
@@ -54,6 +54,7 @@ import org.navalplanner.business.resources.entities.Resource;
import org.navalplanner.business.resources.entities.VirtualWorker;
import org.navalplanner.business.resources.entities.Worker;
import org.navalplanner.web.calendars.IBaseCalendarModel;
+import org.navalplanner.web.common.concurrentdetection.OnConcurrentModification;
import org.navalplanner.web.resources.search.ResourcePredicate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -69,6 +70,7 @@ import org.springframework.transaction.annotation.Transactional;
*/
@Service
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
+@OnConcurrentModification(goToPage = "/resources/worker/worker.zul")
public class WorkerModel implements IWorkerModel {
@Autowired
diff --git a/navalplanner-webapp/src/main/resources/navalplanner-webapp-spring-config.xml b/navalplanner-webapp/src/main/resources/navalplanner-webapp-spring-config.xml
index 28ee981cd..ad9656f0d 100644
--- a/navalplanner-webapp/src/main/resources/navalplanner-webapp-spring-config.xml
+++ b/navalplanner-webapp/src/main/resources/navalplanner-webapp-spring-config.xml
@@ -21,6 +21,10 @@
required for "@Autowired")
-->
+
+
+
+