我正确使用程序化约束定义吗?

时间:2014-09-29 14:19:33

标签: java hibernate-validator

使用较新版本的Hibernate,我注意到我们现在可以通过编程方式定义约束,并且想知道我是否可以使用这种方法来动态定义约束。

基本上我的“DynamicValidator”到目前为止看起来像这样(对于我目前不确定的方法的UnsupportedOperationExceptions):

public abstract class DynamicValidator implements Validator {

    private TypeConstraintMappingContext<?> constraintMappingContext;

    public <T> Set<ConstraintViolation<T>> validate(@Nonnull T object, Class<?>... groups) {
        Validator validator = configureValidator(object);
        return validator.validate(object, groups);
    }

    @Override
    public <T> Set<ConstraintViolation<T>> validateProperty(T object, String propertyName, Class<?>... groups) {
        Validator validator = configureValidator(object);
        return validator.validateProperty(object, propertyName, groups);
    }

    protected void addConstraint(String property, ConstraintDef<?, ?> constraintDef) {
        constraintMappingContext.property(property, ElementType.METHOD).constraint(constraintDef);
    }

    protected void addConstraint(ConstraintDef<?, ?> constraintDef) {
        constraintMappingContext.constraint(constraintDef);
    }

    protected void addConstraintViolation(String property, String messageTemplate) {
        constraintMappingContext.property(property, ElementType.METHOD).constraint(new NotValidDef().message(messageTemplate));
    }

    protected abstract <T> void defineDynamicConstraints(@Nonnull T object);

    private <T> Validator configureValidator(@Nonnull T object) {
        HibernateValidatorConfiguration configuration = Validation.byProvider(HibernateValidator.class).configure();
        ConstraintMapping constraintMapping = configuration.createConstraintMapping();
        constraintMappingContext = constraintMapping.type(object.getClass());
        defineDynamicConstraints(object);
        return configuration.addMapping(constraintMapping).buildValidatorFactory().getValidator();
    }

    @Override
    public <T> Set<ConstraintViolation<T>> validateValue(Class<T> beanType, String propertyName, Object value, Class<?>... groups) {
        throw new UnsupportedOperationException();
    }

    @Override
    public BeanDescriptor getConstraintsForClass(Class<?> clazz) {
        throw new UnsupportedOperationException();
    }

    @Override
    public <T> T unwrap(Class<T> type) {
        throw new UnsupportedOperationException();
    }

    @Override
    public ExecutableValidator forExecutables() {
        throw new UnsupportedOperationException();
    }

}

我担心的是,每次我想验证一个对象时,我实际上都会生成一个新的Validator。那好吗?我的直觉告诉我,我应该重用一个验证器,但似乎我没有配置验证器帖子创建。

1 个答案:

答案 0 :(得分:0)

  

我的直觉告诉我,我应该重复使用一个验证器,

你的直觉是对的。特别是ValidatorFactory个实例应该被缓存。它们的制作成本非常高。此外,通过一直重新构建,您实际上需要反复创建约束元数据,并且无法确保其他缓存的元数据。

我觉得从技术上讲你正在做的事情是可能的,但我会反对,特别是如果表现是你的担忧之一。

您的实际用例是什么?