diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/common/daos/IOrderSequenceDAO.java b/navalplanner-business/src/main/java/org/navalplanner/business/common/daos/IOrderSequenceDAO.java index 1ef346eb2..8886a3ffb 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/common/daos/IOrderSequenceDAO.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/common/daos/IOrderSequenceDAO.java @@ -40,4 +40,8 @@ public interface IOrderSequenceDAO extends IGenericDAO { void remove(OrderSequence orderSequence) throws InstanceNotFoundException, IllegalArgumentException; -} + OrderSequence getActiveOrderSequence(); + + String getNextOrderCode(); + +} \ No newline at end of file diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/common/daos/OrderSequenceDAO.java b/navalplanner-business/src/main/java/org/navalplanner/business/common/daos/OrderSequenceDAO.java index f153298b5..52fbe8df9 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/common/daos/OrderSequenceDAO.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/common/daos/OrderSequenceDAO.java @@ -29,7 +29,10 @@ import org.navalplanner.business.common.exceptions.InstanceNotFoundException; import org.navalplanner.business.i18n.I18nHelper; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; +import org.springframework.orm.hibernate3.HibernateOptimisticLockingFailureException; import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; /** * DAO for {@link OrderSequence}. @@ -72,4 +75,27 @@ public class OrderSequenceDAO extends GenericDAOHibernate remove(orderSequence.getId()); } + @Override + public OrderSequence getActiveOrderSequence() { + return (OrderSequence) getSession().createCriteria(OrderSequence.class) + .add(Restrictions.eq("active", true)).uniqueResult(); + } + + @Override + @Transactional(propagation = Propagation.REQUIRES_NEW) + public String getNextOrderCode() { + for (int i = 0; i < 5; i++) { + try { + OrderSequence orderSequence = getActiveOrderSequence(); + orderSequence.incrementLastValue(); + save(orderSequence); + return orderSequence.getCode(); + } catch (HibernateOptimisticLockingFailureException e) { + // Do nothing (optimistic approach 5 attempts) + } + } + + return null; + } + } \ No newline at end of file diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/common/entities/OrderSequence.java b/navalplanner-business/src/main/java/org/navalplanner/business/common/entities/OrderSequence.java index 3e4d065d4..daff0583f 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/common/entities/OrderSequence.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/common/entities/OrderSequence.java @@ -40,6 +40,8 @@ public class OrderSequence extends BaseEntity { public static final Integer MIN_NUMBER_OF_DIGITS = 5; public static final Integer MAX_NUMBER_OF_DIGITS = 9; + public static final String CODE_SEPARATOR = "-"; + public static OrderSequence create(String prefix) { return create(new OrderSequence(prefix)); } @@ -150,4 +152,12 @@ public class OrderSequence extends BaseEntity { return lastValue > 0; } + public String getCode() { + return prefix + CODE_SEPARATOR + formatValue(numberOfDigits, lastValue); + } + + public void incrementLastValue() { + lastValue++; + } + } \ No newline at end of file diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/common/ConfigurationController.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/ConfigurationController.java index 84d581377..f1d93edd5 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/common/ConfigurationController.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/ConfigurationController.java @@ -22,6 +22,7 @@ package org.navalplanner.web.common; import static org.navalplanner.web.I18nHelper._; +import java.util.ConcurrentModificationException; import java.util.List; import org.navalplanner.business.calendars.entities.BaseCalendar; @@ -104,6 +105,10 @@ public class ConfigurationController extends GenericForwardComposer { reloadWindow(); } catch (ValidationException e) { messages.showInvalidValues(e); + } catch (ConcurrentModificationException e) { + messages.showMessage(Level.ERROR, e.getMessage()); + configurationModel.init(); + reloadWindow(); } } } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/common/ConfigurationModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/ConfigurationModel.java index 439873a7d..7652b659d 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/common/ConfigurationModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/ConfigurationModel.java @@ -23,6 +23,7 @@ package org.navalplanner.web.common; import static org.navalplanner.web.I18nHelper._; import java.util.Collections; +import java.util.ConcurrentModificationException; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -39,6 +40,7 @@ import org.navalplanner.business.i18n.I18nHelper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; +import org.springframework.orm.hibernate3.HibernateOptimisticLockingFailureException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -130,8 +132,14 @@ public class ConfigurationModel implements IConfigurationModel { _("Order sequence prefixes can not be repeated")); } - configurationDAO.save(configuration); - storeAndRemoveOrderSequences(); + try { + configurationDAO.save(configuration); + storeAndRemoveOrderSequences(); + } catch (HibernateOptimisticLockingFailureException e) { + throw new ConcurrentModificationException( + _("Some order was created during the configuration process, it is impossible to update order sequence table. Please, try again later")); + } + } private boolean checkConstraintPrefixNotRepeated() { diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/IOrderModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/IOrderModel.java index ac95d2c52..893e8204b 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/IOrderModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/IOrderModel.java @@ -20,6 +20,7 @@ package org.navalplanner.web.orders; +import java.util.ConcurrentModificationException; import java.util.List; import java.util.Map; @@ -80,7 +81,7 @@ public interface IOrderModel { void initEdit(Order order); - void prepareForCreate(); + void prepareForCreate() throws ConcurrentModificationException; void remove(Order order); diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderCRUDController.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderCRUDController.java index 27a7ea806..14d6abdd6 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderCRUDController.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderCRUDController.java @@ -22,6 +22,7 @@ package org.navalplanner.web.orders; import static org.navalplanner.web.I18nHelper._; +import java.util.ConcurrentModificationException; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -378,8 +379,12 @@ public class OrderCRUDController extends GenericForwardComposer { } public void goToCreateForm() { - orderModel.prepareForCreate(); - showEditWindow(_("Create order")); + try { + orderModel.prepareForCreate(); + showEditWindow(_("Create order")); + } catch (ConcurrentModificationException e) { + messagesForUser.showMessage(Level.ERROR, e.getMessage()); + } } public void setPlanningControllerEntryPoints( diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderModel.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderModel.java index cf3d7bbbe..8fb2a2316 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderModel.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderModel.java @@ -24,6 +24,7 @@ import static org.navalplanner.web.I18nHelper._; import java.util.ArrayList; import java.util.Collection; +import java.util.ConcurrentModificationException; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -38,6 +39,7 @@ import org.navalplanner.business.advance.entities.IndirectAdvanceAssignment; import org.navalplanner.business.calendars.daos.IBaseCalendarDAO; import org.navalplanner.business.calendars.entities.BaseCalendar; import org.navalplanner.business.common.daos.IConfigurationDAO; +import org.navalplanner.business.common.daos.IOrderSequenceDAO; import org.navalplanner.business.common.entities.Configuration; import org.navalplanner.business.common.exceptions.InstanceNotFoundException; import org.navalplanner.business.common.exceptions.ValidationException; @@ -121,6 +123,9 @@ public class OrderModel implements IOrderModel { @Autowired private IConfigurationDAO configurationDAO; + @Autowired + private IOrderSequenceDAO orderSequenceDAO; + @Override public List