Java 使用不同的ConstraintValidatorManager在Spring引导中休眠验证程序
我面临的一个问题在SpringBoot和Hibernate验证中已经提到过,在自定义约束验证器中,依赖项的自动连接不起作用。通过我自己的调试,我注意到当实体级验证发生时,Hibernate加载的ConstraintValidatorManager与Hibernate对表单提交执行bean验证时不同。后者工作正常,前者导致自定义约束验证器的依赖项为空。似乎Hibernate正在从根上下文加载一个管理器,从servlet上下文加载一个管理器。这可以解释为什么Hibernate不知道自定义约束验证器中自动连接的依赖项的存在。然而,如果这是真的,我不知道发生了什么,或者如何让Hibernate/JPA知道Spring上下文及其bean 我希望有人能给我指出正确的方向?我已经尝试了以下所有答案,以及更多(例如,不同的库版本、配置方法、通过utils类加载静态bean等): 另外,我已经专门阅读了几次Spring Boot的参考指南,运气不好。有几个例子提到了它们的Hibernate验证工作良好,无论是对于常规bean提交,还是在实体持久化期间。不幸的是,我似乎无法检索到他们使用的确切(Java)配置,但似乎他们使用的是默认配置。我开始怀疑这是否是一个特定的Spring启动问题(尽管有人说Spring验证和Hibernate验证的组合应该是现成的) 添加任何类似于以下bean的内容都不能解决问题(默认工厂为SpringConstraintValidatorFactory of Course):Java 使用不同的ConstraintValidatorManager在Spring引导中休眠验证程序,java,spring-boot,hibernate-validator,Java,Spring Boot,Hibernate Validator,我面临的一个问题在SpringBoot和Hibernate验证中已经提到过,在自定义约束验证器中,依赖项的自动连接不起作用。通过我自己的调试,我注意到当实体级验证发生时,Hibernate加载的ConstraintValidatorManager与Hibernate对表单提交执行bean验证时不同。后者工作正常,前者导致自定义约束验证器的依赖项为空。似乎Hibernate正在从根上下文加载一个管理器,从servlet上下文加载一个管理器。这可以解释为什么Hibernate不知道自定义约束验证器中
@Bean
公共LocalValidatoryFactoryBean验证器()
{
LocalValidatorFactoryBean=新的LocalValidatorFactoryBean();
setValidationMessageSource(messageSource());
返回豆;
}
也不包括Hibernate验证器的bean定义:
加载和注入所需bean有许多不同的方法,但是如果Hibernate根本不知道在上下文中加载的bean(因为它使用的是不同的上下文?),如何继续
提前谢谢
更新:Gradle文件
buildscript {
ext {
springBootVersion = '2.1.5.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group = '<hidden>'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
jcenter()
}
dependencies {
implementation('org.springframework.boot:spring-boot-starter-web')
implementation('org.springframework.boot:spring-boot-starter-tomcat:2.1.5.RELEASE')
implementation('org.springframework.boot:spring-boot-starter-thymeleaf')
implementation('org.springframework.boot:spring-boot-starter-security')
implementation('org.springframework.boot:spring-boot-starter-data-jpa')
implementation('org.springframework.boot:spring-boot-starter-mail')
implementation('org.springframework.session:spring-session-core')
annotationProcessor('org.springframework.boot:spring-boot-configuration-processor')
implementation('org.postgresql:postgresql')
// https://mvnrepository.com/artifact/org.jboss.aerogear/aerogear-otp-java
implementation('org.jboss.aerogear:aerogear-otp-java:1.0.0')
implementation('com.github.mkopylec:recaptcha-spring-boot-starter:2.2.0')
implementation('nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:2.0.5')
implementation('org.thymeleaf.extras:thymeleaf-extras-springsecurity3:3.0.4.RELEASE')
implementation('javax.enterprise:cdi-api:2.0')
runtimeOnly('org.springframework.boot:spring-boot-devtools')
testImplementation('org.springframework.boot:spring-boot-starter-test')
testImplementation('org.springframework.security:spring-security-test')
testImplementation 'org.mockito:mockito-core:2.27.0'
}
buildscript{
分机{
springBootVersion='2.1.5.RELEASE'
}
存储库{
mavenCentral()
}
依赖关系{
类路径(“org.springframework.boot:spring-boot-gradle插件:${springBootVersion}”)
}
}
应用插件:“java”
应用插件:“eclipse”
应用插件:“org.springframework.boot”
应用插件:“io.spring.dependency management”
组=“”
版本='0.0.1-SNAPSHOT'
sourceCompatibility=1.8
存储库{
mavenCentral()
jcenter()
}
依赖关系{
实现('org.springframework.boot:springbootstarterweb')
实现('org.springframework.boot:springbootstarter-tomcat:2.1.5.RELEASE')
实现('org.springframework.boot:springbootstartermyleaf')
实现('org.springframework.boot:springbootstartersecurity')
实现('org.springframework.boot:springbootstarterdatajpa')
实现('org.springframework.boot:springbootstartermail')
实现('org.springframework.session:spring会话核心')
annotationProcessor('org.springframework.boot:springboot配置处理器')
实现('org.postgresql:postgresql')
// https://mvnrepository.com/artifact/org.jboss.aerogear/aerogear-otp-java
实现('org.jboss.aerogear:aerogear otp java:1.0.0')
实现('com.github.mkopylec:recaptcha spring启动程序:2.2.0')
实现('nz.net.ultraq.thymeleaf:thymeleaf布局方言:2.0.5')
实现('org.thymeleaf.extras:thymeleaf-extras-springsecurity3:3.0.4.RELEASE')
实现('javax.enterprise:cdiapi:2.0')
runtimeOnly('org.springframework.boot:springboot devtools')
testImplementation('org.springframework.boot:springbootstartertest')
testImplementation('org.springframework.security:spring安全测试')
测试实现'org.mockito:mockito核心:2.27.0'
}
通过设置javax.persistence.validation.factory,可以告诉Hibernate使用相同的验证器
@Configuration
@Lazy
class SpringValidatorConfiguration {
@Bean
@Lazy
public HibernatePropertiesCustomizer hibernatePropertiesCustomizer(final Validator validator) {
return new HibernatePropertiesCustomizer() {
@Override
public void customize(Map<String, Object> hibernateProperties) {
hibernateProperties.put("javax.persistence.validation.factory", validator);
}
};
}
}
@配置
@懒惰的
类SpringValidator配置{
@豆子
@懒惰的
公共HibernatePropertiesCustomizer HibernatePropertiesCustomizer(最终验证程序){
返回新的HibernatePropertiesCustomizer(){
@凌驾
公共void自定义(映射hibernateProperties){
hibernateProperties.put(“javax.persistence.validation.factory”,validator);
}
};
}
}
这样,一切都可以正常工作。关于修复,我只想为正在/正在处理此类问题的其他人总结一个更广泛/综合的答案,我的配置现在包含所有这些bean:
@Bean
公共LocalValidatoryFactoryBean验证器()
{
LocalValidatorFactoryBean validatorFactory=新的LocalValidatorFactoryBean();
setValidationMessageSource(messageSource());
返回工厂;
}
@豆子
public MessageSource MessageSource()
{
ReloadableResourceBundleMessageSource=新的ReloadableResourceBundleMessageSource();
setBasename(“类路径:消息”);
messageSource.setDefaultEncoding(“UTF-8”);
返回消息源;
}
@豆子
公共方法验证后处理器方法验证后处理器()
{
MethodValidationPostProcessor MethodValidationPostProcessor=新的MethodValidationPostProcessor();
methodValidationPostProcessor.setValidator(validator());
返回方法验证后处理器;
}
@豆子
公共HibernateProperty