2014-09-29 58 views
0

隨着更新版本的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(); 
    } 

} 

我擔心的是,我基本上是生成新的驗證每次我想驗證一個對象。那還好嗎?我的直覺告訴我,我應該重新使用一個驗證器,但它似乎並不像我可以配置一個驗證器後創建。

回答

0

我的直覺告訴我,我應該重用一個驗證器,

你的直覺是正確的。特別是ValidatorFactory實例應該被緩存。他們創造起來相當昂貴。同樣,通過重新構建,您實際上需要一遍又一遍地創建約束元數據,並且無法確保以其他方式緩存的元數據。

我想技術上你在做什麼是可能的,但我會建議反對它,特別是如果表現是你的擔憂之一。

你的實際用例是什麼?

+0

我想在運行時/動態重用並將約束應用於bean屬性。主要是因爲一個約束可能取決於另一個領域。比如要求結束日期在bean實例的開始日期之後。 – kennyg 2014-09-30 13:37:02

相關問題