diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/common/Registry.java b/navalplanner-business/src/main/java/org/navalplanner/business/common/Registry.java index 2b03022e1..ec528f91d 100644 --- a/navalplanner-business/src/main/java/org/navalplanner/business/common/Registry.java +++ b/navalplanner-business/src/main/java/org/navalplanner/business/common/Registry.java @@ -27,6 +27,7 @@ import org.navalplanner.business.calendars.daos.ICalendarDataDAO; import org.navalplanner.business.calendars.daos.ICalendarExceptionDAO; import org.navalplanner.business.calendars.daos.ICalendarExceptionTypeDAO; import org.navalplanner.business.common.daos.IConfigurationDAO; +import org.navalplanner.business.common.daos.IEntitySequenceDAO; import org.navalplanner.business.costcategories.daos.ICostCategoryDAO; import org.navalplanner.business.costcategories.daos.IHourCostDAO; import org.navalplanner.business.costcategories.daos.IResourcesCostCategoryAssignmentDAO; @@ -186,6 +187,9 @@ public class Registry { @Autowired private ITaskElementDAO taskElementDAO; + @Autowired + private IEntitySequenceDAO entitySequenceDAO; + private Registry() { } @@ -339,4 +343,7 @@ public class Registry { return getInstance().taskElementDAO; } + public static IEntitySequenceDAO getEntitySequenceDAO() { + return getInstance().entitySequenceDAO; + } } diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/common/daos/EntitySequenceDAO.java b/navalplanner-business/src/main/java/org/navalplanner/business/common/daos/EntitySequenceDAO.java new file mode 100644 index 000000000..6d19dcb31 --- /dev/null +++ b/navalplanner-business/src/main/java/org/navalplanner/business/common/daos/EntitySequenceDAO.java @@ -0,0 +1,132 @@ +/* + * This file is part of NavalPlan + * + * Copyright (C) 2009-2010 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.business.common.daos; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang.Validate; +import org.hibernate.NonUniqueResultException; +import org.hibernate.criterion.Restrictions; +import org.navalplanner.business.common.IAdHocTransactionService; +import org.navalplanner.business.common.entities.EntityNameEnum; +import org.navalplanner.business.common.entities.EntitySequence; +import org.navalplanner.business.common.exceptions.InstanceNotFoundException; +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.Repository; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +/** + * DAO for {@link EntitySequence}. + * @author Susana Montes Pedreira + */ +@Repository +@Scope(BeanDefinition.SCOPE_SINGLETON) +public class EntitySequenceDAO extends + GenericDAOHibernate implements IEntitySequenceDAO { + + @Autowired + private IAdHocTransactionService transactionService; + + @Override + public List getAll() { + return list(EntitySequence.class); + } + + @Override + @SuppressWarnings("unchecked") + public List findEntitySquencesNotIn( + List entitySequences) { + List entitySequenceIds = new ArrayList(); + for (EntitySequence entitySequence : entitySequences) { + if (!entitySequence.isNewObject()) { + entitySequenceIds.add(entitySequence.getId()); + } + } + + return getSession().createCriteria(EntitySequence.class).add( + Restrictions.not(Restrictions.in("id", entitySequenceIds))) + .list(); + } + + @Override + public void remove(final EntitySequence entitySequence) + throws InstanceNotFoundException, IllegalArgumentException { + if (entitySequence.getLastValue() > 0) { + throw new IllegalArgumentException( + I18nHelper + ._("You can not remove this order sequence, it is already in use")); + } + + remove(entitySequence.getId()); + } + + @Override + public EntitySequence getActiveEntitySequence(EntityNameEnum entityName) + throws InstanceNotFoundException, NonUniqueResultException { + return (EntitySequence) getSession().createCriteria( + EntitySequence.class).add( + Restrictions.eq("entityName", entityName)).add( + Restrictions.eq("active", true)).uniqueResult(); + } + + @Override + @Transactional(propagation = Propagation.REQUIRES_NEW) + public String getNextEntityCode(EntityNameEnum entityName) { + for (int i = 0; i < 5; i++) { + try { + EntitySequence entitySequence = getActiveEntitySequence(entityName); + entitySequence.incrementLastValue(); + save(entitySequence); + return entitySequence.getCode(); + } catch (HibernateOptimisticLockingFailureException e) { + // Do nothing (optimistic approach 5 attempts) + } catch (InstanceNotFoundException e) { + + } catch (NonUniqueResultException e) { + + } + } + + return null; + } + + @Override + public boolean existOtherActiveSequenceByEntityNameForNewObject( + EntitySequence entitySequence) { + Validate.notNull(entitySequence); + try { + EntitySequence t = getActiveEntitySequence(entitySequence + .getEntityName()); + return (t != null && t != entitySequence); + } catch (InstanceNotFoundException e) { + return false; + } catch (NonUniqueResultException e) { + return true; + } + } + +} \ No newline at end of file diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/common/daos/IEntitySequenceDAO.java b/navalplanner-business/src/main/java/org/navalplanner/business/common/daos/IEntitySequenceDAO.java new file mode 100644 index 000000000..88b623210 --- /dev/null +++ b/navalplanner-business/src/main/java/org/navalplanner/business/common/daos/IEntitySequenceDAO.java @@ -0,0 +1,57 @@ +/* + * This file is part of NavalPlan + * + * Copyright (C) 2009-2010 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.business.common.daos; + +import java.util.List; + +import org.hibernate.NonUniqueResultException; +import org.navalplanner.business.common.entities.EntityNameEnum; +import org.navalplanner.business.common.entities.EntitySequence; +import org.navalplanner.business.common.exceptions.InstanceNotFoundException; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Repository; + +/** + * DAO interface for {@link EntitySequenceDAO}. + * @author Susana Montes Pedreira + */ +@Repository +@Scope(BeanDefinition.SCOPE_SINGLETON) +public interface IEntitySequenceDAO extends IGenericDAO { + + List getAll(); + + List findEntitySquencesNotIn( + List entitySequences); + + void remove(EntitySequence entitySequence) + throws InstanceNotFoundException, IllegalArgumentException; + + EntitySequence getActiveEntitySequence(EntityNameEnum entityName) + throws InstanceNotFoundException, NonUniqueResultException; + + String getNextEntityCode(EntityNameEnum entityName); + + boolean existOtherActiveSequenceByEntityNameForNewObject( + EntitySequence entitySequence); + +} \ No newline at end of file diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/common/entities/EntityNameEnum.java b/navalplanner-business/src/main/java/org/navalplanner/business/common/entities/EntityNameEnum.java new file mode 100644 index 000000000..aa0cc7f4d --- /dev/null +++ b/navalplanner-business/src/main/java/org/navalplanner/business/common/entities/EntityNameEnum.java @@ -0,0 +1,43 @@ +/* + * This file is part of NavalPlan + * + * Copyright (C) 2009-2010 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.business.common.entities; + +import static org.navalplanner.business.i18n.I18nHelper._; + +/** + * It represents the entities which use code generation + * @author Susana Montes Pedreira + */ +public enum EntityNameEnum { + ORDER(_("Order")), CRITERION(_("Criterion")), LABEL(_("Label")), MACHINE( + _("Machine")), WORKER(_("Worker")), UNIT_TYPE(_("Unit type")), CALENDAR( + _("Calendar")); + + private String description; + + private EntityNameEnum(String description) { + this.description = description; + } + + public String getDescription() { + return this.description; + } +} diff --git a/navalplanner-business/src/main/java/org/navalplanner/business/common/entities/EntitySequence.java b/navalplanner-business/src/main/java/org/navalplanner/business/common/entities/EntitySequence.java new file mode 100644 index 000000000..578f6c7fd --- /dev/null +++ b/navalplanner-business/src/main/java/org/navalplanner/business/common/entities/EntitySequence.java @@ -0,0 +1,198 @@ +/* + * This file is part of NavalPlan + * + * Copyright (C) 2009-2010 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.business.common.entities; + +import java.text.DecimalFormat; +import java.text.NumberFormat; + +import org.hibernate.NonUniqueResultException; +import org.hibernate.validator.AssertTrue; +import org.hibernate.validator.NotEmpty; +import org.hibernate.validator.NotNull; +import org.navalplanner.business.common.BaseEntity; +import org.navalplanner.business.common.IntegrationEntity; +import org.navalplanner.business.common.Registry; +import org.navalplanner.business.common.daos.IEntitySequenceDAO; +import org.navalplanner.business.common.exceptions.InstanceNotFoundException; +import org.navalplanner.business.i18n.I18nHelper; + +/** + * Sequence for {@link IntegrationEntity} codes. + * @author Susana Montes Pedreira + */ +public class EntitySequence extends BaseEntity { + + public static final Integer MIN_NUMBER_OF_DIGITS = 5; + public static final Integer MAX_NUMBER_OF_DIGITS = 9; + + public static EntitySequence create(String prefix, EntityNameEnum entityName) { + return create(new EntitySequence(prefix, entityName)); + } + + /** + * Constructor for hibernate. Do not use! + */ + public EntitySequence() { + } + + public EntitySequence(String prefix, EntityNameEnum entityName) { + this.prefix = prefix; + this.entityName = entityName; + } + + private String prefix; + + private EntityNameEnum entityName; + + private Integer lastValue = 0; + + private Integer numberOfDigits = MIN_NUMBER_OF_DIGITS; + + private Boolean active = false; + + public void setPrefix(String prefix) throws IllegalArgumentException { + if (isAlreadyInUse()) { + throw new IllegalArgumentException( + I18nHelper + ._("You can not modifiy this order sequence, it is already in use")); + } + + this.prefix = prefix; + } + + @NotEmpty(message = "prefix not specified") + public String getPrefix() { + if (prefix != null) { + prefix = prefix.trim(); + } + return prefix; + } + + @NotNull(message = "last value not specified") + public Integer getLastValue() { + return lastValue; + } + + @AssertTrue(message = "prefix must not contain white spaces") + public boolean checkConstraintPrefixWithoutWhiteSpaces() { + if ((prefix == null) || (prefix.isEmpty())) { + return false; + } + + return !prefix.contains(" "); + } + + public void setActive(Boolean active) { + this.active = active; + } + + public Boolean isActive() { + return active; + } + + public void setNumberOfDigits(Integer numberOfDigits) + throws IllegalArgumentException { + if (isAlreadyInUse()) { + throw new IllegalArgumentException( + I18nHelper + ._("You can not modifiy this order sequence, it is already in use")); + } + + if ((numberOfDigits != null) + && (numberOfDigits >= MIN_NUMBER_OF_DIGITS) + && (numberOfDigits <= MAX_NUMBER_OF_DIGITS)) { + this.numberOfDigits = numberOfDigits; + } else { + throw new IllegalArgumentException(I18nHelper._( + "number of digits must be between {0} and {1}", + MIN_NUMBER_OF_DIGITS, MAX_NUMBER_OF_DIGITS)); + } + } + + @NotNull(message = "number of digits not specified") + public Integer getNumberOfDigits() { + return numberOfDigits; + } + + @AssertTrue(message = "number of digits is out of range") + public boolean checkConstraintNumberOfDigitsInRange() { + if ((numberOfDigits != null) + && (numberOfDigits >= MIN_NUMBER_OF_DIGITS) + && (numberOfDigits <= MAX_NUMBER_OF_DIGITS)) { + return true; + } + return false; + } + + public static String formatValue(int numberOfDigits, int value) { + String format = ""; + for (int i = 0; i < numberOfDigits; i++) { + format += "0"; + } + + NumberFormat numberFormat = new DecimalFormat(format); + return numberFormat.format(value); + } + + public boolean isAlreadyInUse() { + return lastValue > 0; + } + + public String getCode() { + return prefix + formatValue(numberOfDigits, lastValue); + } + + public void incrementLastValue() { + lastValue++; + } + + @NotNull(message = "entity name not specified") + public EntityNameEnum getEntityName() { + return entityName; + } + + public void setEntityName(EntityNameEnum entityName) { + this.entityName = entityName; + } + + @AssertTrue(message = "Only one sequence for each entity can be active at the same time.") + public boolean checkConstraintOnlyOneSequenceForEachEntityIsActive() { + if (!isActive()) { + return true; + } + + IEntitySequenceDAO entitySequenceDAO = Registry.getEntitySequenceDAO(); + if (isNewObject()) { + return !entitySequenceDAO + .existOtherActiveSequenceByEntityNameForNewObject(this); + } else { + try { + EntitySequence c = entitySequenceDAO + .getActiveEntitySequence(this.entityName); + return c.getId().equals(getId()); + } catch (NonUniqueResultException e) { + return false; + } catch (InstanceNotFoundException e) { + return true; + } + } + } +} \ No newline at end of file diff --git a/navalplanner-business/src/main/resources/navalplanner-business-spring-config.xml b/navalplanner-business/src/main/resources/navalplanner-business-spring-config.xml index fa0adce1e..82424fd87 100644 --- a/navalplanner-business/src/main/resources/navalplanner-business-spring-config.xml +++ b/navalplanner-business/src/main/resources/navalplanner-business-spring-config.xml @@ -75,6 +75,9 @@ org/navalplanner/business/common/entities/OrderSequence.hbm.xml + + org/navalplanner/business/common/entities/EntitySequence.hbm.xml + org/navalplanner/business/externalcompanies/entities/ExternalCompanies.hbm.xml diff --git a/navalplanner-business/src/main/resources/org/navalplanner/business/common/entities/EntitySequence.hbm.xml b/navalplanner-business/src/main/resources/org/navalplanner/business/common/entities/EntitySequence.hbm.xml new file mode 100644 index 000000000..8ada7f2e7 --- /dev/null +++ b/navalplanner-business/src/main/resources/org/navalplanner/business/common/entities/EntitySequence.hbm.xml @@ -0,0 +1,27 @@ + + + + + + + + + 100 + + + + + + + org.navalplanner.business.common.entities.EntityNameEnum + + + + + + + + + + diff --git a/navalplanner-business/src/test/java/org/navalplanner/business/common/EntitySequenceTest.java b/navalplanner-business/src/test/java/org/navalplanner/business/common/EntitySequenceTest.java new file mode 100644 index 000000000..72c2e03ab --- /dev/null +++ b/navalplanner-business/src/test/java/org/navalplanner/business/common/EntitySequenceTest.java @@ -0,0 +1,226 @@ +/* + * This file is part of NavalPlan + * + * Copyright (C) 2009-2010 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.business.common; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.navalplanner.business.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_FILE; +import static org.navalplanner.business.test.BusinessGlobalNames.BUSINESS_SPRING_CONFIG_TEST_FILE; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.navalplanner.business.common.daos.IEntitySequenceDAO; +import org.navalplanner.business.common.entities.EntityNameEnum; +import org.navalplanner.business.common.entities.EntitySequence; +import org.navalplanner.business.common.exceptions.InstanceNotFoundException; +import org.navalplanner.business.common.exceptions.ValidationException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.NotTransactional; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.annotation.Transactional; + +/** + * Tests for {@link EntitySequence}.
+ * @author Susana Montes Pedreira + */ + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(locations = { BUSINESS_SPRING_CONFIG_FILE, + BUSINESS_SPRING_CONFIG_TEST_FILE }) +@Transactional +public class EntitySequenceTest { + + @Autowired + IEntitySequenceDAO entitySequenceDAO; + + @Autowired + private IAdHocTransactionService transactionService; + + @Test + public void testCreateActiveEntitySequence() throws Exception { + try { + entitySequenceDAO.save(givenEntitySequence("prefix_test", + EntityNameEnum.CALENDAR, true)); + entitySequenceDAO.flush(); + } catch (ValidationException e) { + fail("It should not throw an exception"); + } + assertTrue(entitySequenceDAO.getAll().size() == 1); + + } + + @Test + public void testCreateEntitySequenceWithEmptyPrefix() throws Exception { + try { + entitySequenceDAO.save(givenEntitySequence("", + EntityNameEnum.CALENDAR, true)); + fail("It should throw an exception"); + } catch (ValidationException e) { + // It should throw an exception + } + + } + + @Test + public void testCreateEntitySequenceWithPrefixWithWhiteSpace() + throws Exception { + try { + entitySequenceDAO.save(givenEntitySequence( + "prefix with white spaces", EntityNameEnum.CALENDAR, true)); + fail("It should throw an exception"); + } catch (ValidationException e) { + // It should throw an exception + } + + } + + @Test + public void testCreateEntitySequenceWithEmptyEntityName() throws Exception { + try { + entitySequenceDAO.save(givenEntitySequence("prefix", null, false)); + fail("It should throw an exception"); + } catch (ValidationException e) { + // It should throw an exception + } + + } + + @Test + public void testCreateEntitySequenceWithNumberOfDigitsNotSpecified() + throws Exception { + try { + EntitySequence entitySequence = givenEntitySequence("prefix", + EntityNameEnum.CRITERION, true); + entitySequence.setNumberOfDigits(null); + entitySequenceDAO.save(entitySequence); + fail("It should throw an exception"); + } catch (IllegalArgumentException e) { + // It should throw an exception + } + + } + + @Test + public void testCreateEntitySequenceWithNumberOfDigitsOutRange() + throws Exception { + try { + EntitySequence entitySequence = givenEntitySequence("prefix", + EntityNameEnum.CRITERION, true); + entitySequence.setNumberOfDigits(15); + entitySequenceDAO.save(entitySequence); + fail("It should throw an exception"); + } catch (IllegalArgumentException e) { + // It should throw an exception + } + + } + + @Test + @NotTransactional + public void testCreateTwoActiveEntitySequenceWithTheSameEntityName() { + EntitySequence entitySequenceA = givenEntitySequence("prefixA", + EntityNameEnum.CRITERION, true); + saveEntitySequenceInTransaction(entitySequenceA); + try { + EntitySequence entitySequenceB = givenEntitySequence("prefixB", + EntityNameEnum.CRITERION, true); + saveEntitySequenceInTransaction(entitySequenceB); + fail("Expected ValidationException"); + } catch (ValidationException e) { + } + } + + @Test + @NotTransactional + public void testCreateTwoEntitySequenceWithTheSameEntityName() { + EntitySequence entitySequenceA = givenEntitySequence("prefixA", + EntityNameEnum.LABEL, true); + saveEntitySequenceInTransaction(entitySequenceA); + try { + EntitySequence entitySequenceB = givenEntitySequence("prefixB", + EntityNameEnum.LABEL, false); + saveEntitySequenceInTransaction(entitySequenceB); + } catch (ValidationException e) { + fail("It shouldn't throw an exception"); + } + } + + @Test + @NotTransactional + public void testCreateAndRemoveTwoEntitySequenceWithTheSameEntityName() { + EntitySequence entitySequenceA = givenEntitySequence("prefixA", + EntityNameEnum.MACHINE, true); + saveEntitySequenceInTransaction(entitySequenceA); + try { + removeEntitySequenceInTransaction(entitySequenceA); + } catch (ValidationException e) { + fail("It shouldn't throw an exception"); + } + try { + EntitySequence entitySequenceB = givenEntitySequence("prefixB", + EntityNameEnum.MACHINE, true); + saveEntitySequenceInTransaction(entitySequenceB); + } catch (ValidationException e) { + fail("It shouldn't throw an exception"); + } + } + + private void saveEntitySequenceInTransaction( + final EntitySequence entitySequence) { + IOnTransaction createEntitySequenceTransaction = new IOnTransaction() { + + @Override + public Void execute() { + entitySequenceDAO.save(entitySequence); + return null; + } + }; + transactionService.runOnTransaction(createEntitySequenceTransaction); + } + + private void removeEntitySequenceInTransaction( + final EntitySequence entitySequence) { + IOnTransaction createEntitySequenceTransaction = new IOnTransaction() { + + @Override + public Void execute() { + try { + entitySequenceDAO.remove(entitySequence); + } catch (InstanceNotFoundException e) { + + } catch (IllegalArgumentException e) { + + } + return null; + } + }; + transactionService.runOnTransaction(createEntitySequenceTransaction); + } + + private EntitySequence givenEntitySequence(String prefix, + EntityNameEnum entityName, boolean active) { + EntitySequence entitySequence = EntitySequence.create(prefix, + entityName); + entitySequence.setActive(active); + return entitySequence; + } +} diff --git a/navalplanner-business/src/test/resources/navalplanner-business-spring-config-test.xml b/navalplanner-business/src/test/resources/navalplanner-business-spring-config-test.xml index 109c94173..41fc4da0e 100644 --- a/navalplanner-business/src/test/resources/navalplanner-business-spring-config-test.xml +++ b/navalplanner-business/src/test/resources/navalplanner-business-spring-config-test.xml @@ -81,6 +81,9 @@ org/navalplanner/business/common/entities/OrderSequence.hbm.xml + + org/navalplanner/business/common/entities/EntitySequence.hbm.xml + org/navalplanner/business/externalcompanies/entities/ExternalCompanies.hbm.xml