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
的自定义版本可能会对此有所帮助(假设您是通过这种方式获得验证器的)。