ItEr34S11ArquitecturaServidorItEr33S13: Improvements to validation architecture.
"validate" method has been added to BaseEntity, GenericDAOHibernate has been refactored to use BaseEntity's "validate" method, @AssertTrue annotation has been uncommented in method "checkConstraintUniqueCriterionTypeName" in CriterionType entity and "validate" method removed, test cases fixed in CriterionTypeDAOTest ("testCriterionTypeCanBeSavedTwice" was removed since it was not conceptually correct, "testCannotSaveTwoDifferentCriterionTypesWithTheSameName" was implemented
wrongly), and finally, CriterionServiceREST now uses "GenericDao::save" to validate and save.
This commit is contained in:
parent
525fa4a556
commit
5ada35d5a5
5 changed files with 28 additions and 82 deletions
|
|
@ -20,7 +20,10 @@
|
|||
|
||||
package org.navalplanner.business.common;
|
||||
|
||||
import org.hibernate.validator.ClassValidator;
|
||||
import org.hibernate.validator.InvalidValue;
|
||||
import org.navalplanner.business.INewObject;
|
||||
import org.navalplanner.business.common.exceptions.ValidationException;
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -29,6 +32,7 @@ import org.navalplanner.business.INewObject;
|
|||
* It provides the basic behavior for id and version fields.
|
||||
*
|
||||
* @author Manuel Rego Casasnovas <mrego@igalia.com>
|
||||
* @author Fernando Bellas Permuy <fbellas@udc.es>
|
||||
*/
|
||||
public abstract class BaseEntity implements INewObject {
|
||||
|
||||
|
|
@ -80,4 +84,13 @@ public abstract class BaseEntity implements INewObject {
|
|||
setNewObject(false);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void validate() throws ValidationException {
|
||||
ClassValidator classValidator = new ClassValidator(this.getClass());
|
||||
InvalidValue[] invalidValues = classValidator.getInvalidValues(this);
|
||||
if (invalidValues.length > 0) {
|
||||
throw new ValidationException(invalidValues);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,8 +32,7 @@ import org.hibernate.SessionFactory;
|
|||
import org.hibernate.StaleObjectStateException;
|
||||
import org.hibernate.criterion.Projections;
|
||||
import org.hibernate.criterion.Restrictions;
|
||||
import org.hibernate.validator.ClassValidator;
|
||||
import org.hibernate.validator.InvalidValue;
|
||||
import org.navalplanner.business.common.BaseEntity;
|
||||
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
|
||||
import org.navalplanner.business.common.exceptions.ValidationException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
|
@ -57,8 +56,8 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
* @param <PK>
|
||||
* Primary key class
|
||||
*/
|
||||
public class GenericDAOHibernate<E, PK extends Serializable> implements
|
||||
IGenericDAO<E, PK> {
|
||||
public class GenericDAOHibernate<E extends BaseEntity,
|
||||
PK extends Serializable> implements IGenericDAO<E, PK> {
|
||||
|
||||
private Class<E> entityClass;
|
||||
|
||||
|
|
@ -81,20 +80,10 @@ public class GenericDAOHibernate<E, PK extends Serializable> implements
|
|||
}
|
||||
|
||||
public void save(E entity) throws ValidationException {
|
||||
checkIsValid(entity);
|
||||
entity.validate();
|
||||
getSession().saveOrUpdate(entity);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void checkIsValid(E entity) throws ValidationException {
|
||||
Class<E> entityClass = (Class<E>) entity.getClass();
|
||||
ClassValidator<E> classValidator = new ClassValidator<E>(entityClass);
|
||||
InvalidValue[] invalidValues = classValidator.getInvalidValues(entity);
|
||||
if (invalidValues.length > 0) {
|
||||
throw new ValidationException(invalidValues);
|
||||
}
|
||||
}
|
||||
|
||||
public void reattachUnmodifiedEntity(E entity) {
|
||||
|
||||
getSession().lock(entity, LockMode.NONE);
|
||||
|
|
|
|||
|
|
@ -20,14 +20,11 @@
|
|||
|
||||
package org.navalplanner.business.resources.entities;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang.builder.EqualsBuilder;
|
||||
import org.hibernate.validator.AssertTrue;
|
||||
import org.hibernate.validator.ClassValidator;
|
||||
import org.hibernate.validator.InvalidValue;
|
||||
import org.hibernate.validator.NotEmpty;
|
||||
import org.hibernate.validator.Valid;
|
||||
import org.navalplanner.business.common.BaseEntity;
|
||||
|
|
@ -284,12 +281,7 @@ public class CriterionType extends BaseEntity implements
|
|||
|
||||
}
|
||||
|
||||
// FIXME: Surprisingly, @AssertTrue in this method causes the Maven build to
|
||||
// fail due to out of memory (probably due to the configuration of Hibernate to
|
||||
// automatically execute validations when saving entities). Provisionally,
|
||||
// "validate" method has been provided as a hack.
|
||||
// FIXME: Internationalization must be provided.
|
||||
// @AssertTrue(message="el nombre del tipo de criterion ya se está usando")
|
||||
@AssertTrue(message="el nombre del tipo de criterion ya se está usando")
|
||||
public boolean checkConstraintUniqueCriterionTypeName() {
|
||||
|
||||
ICriterionTypeDAO criterionTypeDAO = Registry.getCriterionTypeDAO();
|
||||
|
|
@ -340,28 +332,4 @@ public class CriterionType extends BaseEntity implements
|
|||
|
||||
}
|
||||
|
||||
// FIXME: hack to overcome problem with @AssertTrue and
|
||||
// "checkConstraintUniqueCriterionTypeName" method.
|
||||
public InvalidValue[] validate() {
|
||||
|
||||
ClassValidator<CriterionType> criterionTypeValidator =
|
||||
new ClassValidator<CriterionType>(CriterionType.class);
|
||||
|
||||
InvalidValue[] invalidValues =
|
||||
criterionTypeValidator.getInvalidValues(this);
|
||||
|
||||
if (!checkConstraintUniqueCriterionTypeName()) {
|
||||
invalidValues =
|
||||
Arrays.copyOf(invalidValues, invalidValues.length+1);
|
||||
invalidValues[invalidValues.length-1] =
|
||||
new InvalidValue("el nombre del tipo de criterion ya se " +
|
||||
"está usando", CriterionType.class,
|
||||
"checkConstraintUniqueCriterionTypeName",
|
||||
null, this);
|
||||
}
|
||||
|
||||
return invalidValues;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ package org.navalplanner.business.test.resources.daos;
|
|||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.assertFalse;
|
||||
import static junit.framework.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;
|
||||
|
||||
|
|
@ -31,7 +30,6 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.hibernate.exception.ConstraintViolationException;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.navalplanner.business.common.exceptions.InstanceNotFoundException;
|
||||
|
|
@ -40,7 +38,6 @@ import org.navalplanner.business.resources.daos.ICriterionTypeDAO;
|
|||
import org.navalplanner.business.resources.entities.CriterionType;
|
||||
import org.navalplanner.business.resources.entities.ResourceEnum;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
|
@ -82,30 +79,13 @@ public class CriterionTypeDAOTest {
|
|||
assertTrue(criterionTypeDAO.exists(criterionType.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCriterionTypeCanBeSavedTwice() throws ValidationException {
|
||||
CriterionType criterionType = createValidCriterionType();
|
||||
criterionTypeDAO.save(criterionType);
|
||||
criterionTypeDAO.save(criterionType);
|
||||
assertTrue(criterionTypeDAO.exists(criterionType.getId())
|
||||
|| criterionTypeDAO.existsByName(criterionType));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(expected=ValidationException.class)
|
||||
public void testCannotSaveTwoDifferentCriterionTypesWithTheSameName()
|
||||
throws ValidationException {
|
||||
try {
|
||||
CriterionType criterionType = createValidCriterionType("bla","");
|
||||
criterionTypeDAO.save(criterionType);
|
||||
criterionType = createValidCriterionType("bla","");
|
||||
criterionTypeDAO.save(criterionType);
|
||||
criterionTypeDAO.flush();
|
||||
fail("must send exception since thereis a duplicated criterion type");
|
||||
} catch (ConstraintViolationException c) {
|
||||
// This exception is raised in postgresql
|
||||
} catch (DataIntegrityViolationException d) {
|
||||
// This exception is raised in HSQL
|
||||
}
|
||||
CriterionType criterionType = createValidCriterionType("bla","");
|
||||
criterionTypeDAO.save(criterionType);
|
||||
criterionType = createValidCriterionType("bla","");
|
||||
criterionTypeDAO.save(criterionType);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import javax.ws.rs.POST;
|
|||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
|
||||
import org.hibernate.validator.InvalidValue;
|
||||
import org.navalplanner.business.common.exceptions.ValidationException;
|
||||
import org.navalplanner.business.resources.daos.ICriterionTypeDAO;
|
||||
import org.navalplanner.business.resources.entities.CriterionType;
|
||||
import org.navalplanner.ws.common.api.InstanceConstraintViolationsDTO;
|
||||
|
|
@ -86,19 +86,15 @@ public class CriterionServiceREST implements ICriterionService {
|
|||
|
||||
CriterionType criterionType =
|
||||
CriterionConverter.toEntity(criterionTypeDTO);
|
||||
InvalidValue[] invalidValues =
|
||||
criterionType.validate();
|
||||
|
||||
if (invalidValues.length > 0) {
|
||||
|
||||
try {
|
||||
criterionTypeDAO.save(criterionType);
|
||||
} catch (ValidationException e) {
|
||||
instanceConstraintViolationsList.add(
|
||||
ConstraintViolationConverter.toDTO(
|
||||
generateInstanceId(instanceNumber,
|
||||
criterionTypeDTO.name),
|
||||
invalidValues));
|
||||
|
||||
} else {
|
||||
criterionTypeDAO.save(criterionType);
|
||||
e.getInvalidValues()));
|
||||
}
|
||||
|
||||
instanceNumber++;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue