Java 编程约束定义并重新定义默认组

Java 编程约束定义并重新定义默认组,java,hibernate,validation,bean-validation,hibernate-validator,Java,Hibernate,Validation,Bean Validation,Hibernate Validator,我想使用编程约束定义重新定义默认组: constraintMapping.type(User.class) .defaultGroupSequence(AlwaysCheck.class, User.class) .property("name", ElementType.FIELD) .constraint( new LengthDef().max(1) .groups(AlwaysCheck.class) .message("

我想使用编程约束定义重新定义默认组:

constraintMapping.type(User.class)
   .defaultGroupSequence(AlwaysCheck.class, User.class)
   .property("name", ElementType.FIELD)
   .constraint(
        new LengthDef().max(1)
        .groups(AlwaysCheck.class)
        .message("text"))
当我将对象持久化到数据库中时,检查不会发生

在注释中给定时,相同的约束也会起作用:

@GroupSequence({AlwaysCheck.class, User.class})
public class User implements Serializable {
    //...
    @Length(max = 1, message = "text", groups = {AlwaysCheck.class})         
    private String name;
}
如何将其表示为程序

解决方案

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" >
   ...
    <property name="hibernateProperties">
        <props>                                
       ...
            <prop key="javax.persistence.validation.factory">#{validator}</prop>                
        </props>
    </property>                
  </bean>

...
...
#{validator}
UPDATE2@Gunnar

在Spring上下文中,我创建了bean

       <bean id="validator" class="....LocalValidatorFactoryBeanOverride">          
           <property name="validationMessageSource" ref="messageSource"/>                                  
           <property name="constraintMappingFactory" ref="constraintMappingFactoryComponent" />                    
       </bean>

     //...
     public class LocalValidatorFactoryBeanOverride extends SpringValidatorAdapterOverride
    implements ValidatorFactory, ApplicationContextAware, InitializingBean {

   //UPDATE My constraint definition
   private ConstraintMappingFactory constraintMappingFactory;

   //..
   @SuppressWarnings("unchecked")
public void afterPropertiesSet() {
    @SuppressWarnings("rawtypes")
    Configuration configuration = (this.providerClass != null ?
            Validation.byProvider(this.providerClass).configure() :
            Validation.byDefaultProvider().configure());

    MessageInterpolator targetInterpolator = this.messageInterpolator;
    if (targetInterpolator == null) {
        targetInterpolator = configuration.getDefaultMessageInterpolator();
    }
    configuration.messageInterpolator(new LocaleContextMessageInterpolator(targetInterpolator));

    if (this.traversableResolver != null) {
        configuration.traversableResolver(this.traversableResolver);
    }

    ConstraintValidatorFactory targetConstraintValidatorFactory = this.constraintValidatorFactory;
    if (targetConstraintValidatorFactory == null && this.applicationContext != null) {
        targetConstraintValidatorFactory =
                new SpringConstraintValidatorFactory(this.applicationContext.getAutowireCapableBeanFactory());
    }
    if (targetConstraintValidatorFactory != null) {
        configuration.constraintValidatorFactory(targetConstraintValidatorFactory);
    }

    if (this.mappingLocations != null) {
        for (Resource location : this.mappingLocations) {
            try {
                configuration.addMapping(location.getInputStream());
            }
            catch (IOException ex) {
                throw new IllegalStateException("Cannot read mapping resource: " + location);
            }
        }
    }

    for (Map.Entry<String, String> entry : this.validationPropertyMap.entrySet()) {
        configuration.addProperty(entry.getKey(), entry.getValue());
    }

            if(constraintMappingFactory != null) {

                if(configuration instanceof HibernateValidatorConfiguration) {

                    HibernateValidatorConfiguration hibernateValidatorConfiguration = (HibernateValidatorConfiguration) configuration;

                    ConstraintMapping constraintMapping = constraintMappingFactory.getConstraintMapping(hibernateValidatorConfiguration);                        
                    hibernateValidatorConfiguration.addMapping(constraintMapping);
                }                    
            }



    this.validatorFactory = configuration.buildValidatorFactory();                
    setTargetValidator(this.validatorFactory.getValidator());
}

   }

//...
公共类LocalValidatorFactoryBeanOverride扩展了SpringValidatorAdapterOverride
实现ValidatorFactory、ApplicationContextAware、InitializingBean{
//更新我的约束定义
私有约束映射工厂约束映射工厂;
//..
@抑制警告(“未选中”)
公共无效afterPropertiesSet(){
@抑制警告(“原始类型”)
配置=(this.providerClass!=null?
Validation.byProvider(this.providerClass).configure():
Validation.byDefaultProvider().configure());
MessageInterpolator targetInterpolator=this.MessageInterpolator;
if(targetInterpolator==null){
targetInterpolator=configuration.getDefaultMessageInterpolator();
}
messageInterpolator(新的LocaleContextMessageInterpolator(targetInterpolator));
if(this.traversableResolver!=null){
configuration.traversableResolver(这个.traversableResolver);
}
ConstraintValidatorFactory targetConstraintValidatorFactory=this.ConstraintValidatorFactory;
if(targetConstraintValidatorFactory==null&&this.applicationContext!=null){
目标约束验证数据工厂=
新的SpringConstraintValidatorFactory(this.applicationContext.getAutowireCapableBeanFactory());
}
if(targetConstraintValidatorFactory!=null){
配置.constraintValidatorFactory(targetConstraintValidatorFactory);
}
if(this.mappingLocations!=null){
用于(资源位置:this.mappingLocations){
试一试{
addMapping(location.getInputStream());
}
捕获(IOEX异常){
抛出新的IllegalStateException(“无法读取映射资源:+位置”);
}
}
}
for(Map.Entry:this.validationPropertyMap.entrySet()){
configuration.addProperty(entry.getKey(),entry.getValue());
}
if(constraintMappingFactory!=null){
if(HibernateValidatorConfiguration的配置实例){
HibernateValidatorConfiguration HibernateValidatorConfiguration=(HibernateValidatorConfiguration)配置;
ConstraintMapping ConstraintMapping=constraintMappingFactory.getConstraintMapping(hibernateValidatorConfiguration);
hibernateValidatorConfiguration.addMapping(约束映射);
}                    
}
this.validatorFactory=configuration.buildValidatorFactory();
setTargetValidator(this.validatorFactory.getValidator());
}
}

是否添加在引导验证程序工厂时创建的映射?需要这样做:

Validator validator = configuration.addMapping( constraintMapping )
    .buildValidatorFactory()
    .getValidator();     

当然可以。除了defaultGroupSequence之外,一切都正常。手动调用使用该映射配置的
验证器
,可以得到预期的结果。但是我知道你希望这个定义在坚持的时候被应用。在这种情况下,您是如何触发验证的?这是通过JPA触发的默认生命周期验证实现的吗?那么,您如何传递已配置的
验证程序
实例?你是说应用了编程配置的@Length约束吗?谢谢你的回答。我不使用JPA。在会话/事务Hibernate中,我从DB加载用户对象,并设置字段名-setName(“12345”)。当关闭事务(声明性Spring)时,我希望得到一个异常。这并没有发生。如果我手动调用validator.validate(user,AlwaysCheck.Class),我会得到正确的验证错误。如果我使用基于注释的方法(非编程),当事务关闭时,我会得到正确的异常,无需手动检查。感觉编程方法不会更改默认组,而持久化对象和验证机制(EventListiner right?)使用Default.class组。那么如何设置事务提交时使用的验证器呢?您需要确保使用您配置的约束映射引导此实例。Spring的
LocalValidatoryFactoryBean
的自定义版本可能会对此有所帮助(假设您是通过这种方式获得验证器的)。