Java 自定义约束验证程序中的自动连线存储库为空
我有一个基于Spring的webapp。我在控制器中使用了几个带有注释@repository、@Transactional的存储库类。那部分很好用 我创建了一个自定义约束验证器,它必须访问存储库。现在我无法理解为什么存储库为空。我尝试用@Component注释验证程序。包含所有这些类的基本包位于xml部分。那么,我还应该做些什么来确保存储库依赖项注入工作呢。这就是我的约束验证器的样子Java 自定义约束验证程序中的自动连线存储库为空,java,spring,hibernate,validation,bean-validation,Java,Spring,Hibernate,Validation,Bean Validation,我有一个基于Spring的webapp。我在控制器中使用了几个带有注释@repository、@Transactional的存储库类。那部分很好用 我创建了一个自定义约束验证器,它必须访问存储库。现在我无法理解为什么存储库为空。我尝试用@Component注释验证程序。包含所有这些类的基本包位于xml部分。那么,我还应该做些什么来确保存储库依赖项注入工作呢。这就是我的约束验证器的样子 public class DonorTypeExistsConstraintValidator implemen
public class DonorTypeExistsConstraintValidator implements
ConstraintValidator<DonorTypeExists, DonorType> {
@Autowired
private DonorTypeRepository donorTypeRepository;
@Override
public void initialize(DonorTypeExists constraint) {
}
public boolean isValid(DonorType target, ConstraintValidatorContext context) {
System.out.println("donorType: " + target);
if (target == null)
return true;
try {
if (donorTypeRepository.isDonorTypeValid(target.getDonorType()))
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public void setDonorRepository(DonorTypeRepository donorTypeRepository) {
this.donorTypeRepository = donorTypeRepository;
}
}
公共类DonorTypeExistsConstraintValidator实现
约束校验器{
@自动连线
私有DonorTypeRepository DonorTypeRepository;
@凌驾
公共void初始化(DonorTypeExists约束){
}
公共布尔值有效(DonorType目标、CONSTRAINTVALIDATOR上下文){
System.out.println(“donorType:+target”);
if(target==null)
返回true;
试一试{
if(donorTypeRepository.isDonorTypeValid(target.getDonorType()))
返回true;
}捕获(例外e){
e、 printStackTrace();
}
返回false;
}
public void setDonorRepository(DonorTypeRepository DonorTypeRepository){
this.donorTypeRepository=donorTypeRepository;
}
}
更新
包扫描配置:
<context:annotation-config />
<!-- Configures the @Controller programming model -->
<mvc:annotation-driven />
<context:component-scan base-package="controller" />
<context:component-scan base-package="repository" />
<context:component-scan base-package="model" />
<context:component-scan base-package="viewmodel" />
此类位于包model.donortype中。
存储库位于包存储库中
更新
更令人费解的是,删除所有预插入侦听器(在本例中只有BeanValidationEventListener)修复了自动连接问题。这使事情更加复杂
我甚至没有按照下面的回答插入BeanValidationEventListener。这实际上与此处的建议相反:
@覆盖
public void Integration(配置、SessionFactoryImplementor实现程序、,
SessionFactoryServiceRegistry(注册中心){
info(“注册事件侦听器”);
System.out.println(“此处”);
//您可以为重复注册添加复制策略
final EventListenerRegistry eventRegistry=registry.getService(EventListenerRegistry.class);
//在前添加到寄存器或在后添加到寄存器
//此示例将注册一个持久化事件侦听器
eventRegistry.prependListeners(EventType.PERSIST,EntitySaveListener.class);
appendListeners(EventType.MERGE,EntitySaveListener.class);
迭代器iter=eventRegistry.getEventListenerGroup(EventType.PRE_INSERT).listeners().Iterator();
while(iter.hasNext()){
PreInsertEventListener el=iter.next();
System.out.println(el.getClass());
BeanValidationEventListener侦听器=(BeanValidationEventListener)el;
System.out.println(侦听器);
iter.remove();
}
}
更新
我正在使用JPA。我有JPA实体的支持表格。在控制器中,我使用InitBinder实例化一个自定义验证器binder.setValidator(新的EntityBackingFormValidator(binder.getValidator())代码>。
以下是此操作的代码:
此自定义验证器调用默认验证器上的验证,并留下执行一些自定义验证的范围。
我正在实体中使用注释来创建约束。除了默认约束之外,我还需要定义一些约束来检查多对一映射另一侧的实体是否存在。
这是自定义约束验证器。
现在,此自定义约束验证器中的自动连线存储库为空。我正在尝试在这里提供的CustomIntegrator中自定义代码
以及这里的xml配置文件
希望实际的代码能帮助您回答我的问题。
谢谢 您使用的是哪家验证器工厂。或者换一种说法,对你来说很热的引导Bean验证?默认Bean验证(以及Hibernate验证程序作为引用实现)不会将依赖项注入ConstraintValidator实例。至少在Bean Validation 1.0中
要启用依赖项注入,必须配置自定义ConstraintValidatorFactory。Spring提供了SpringConstraintValidatorFactory,这是使用LocalValidatorFactoryBean时的默认设置-请参阅
还有,你在用JPA吗?我假设是这样,在这种情况下,生命周期事件的自动验证会自动进行。您可以使用属性javax.persistence.validation.mode并将其设置为“无”,而不是尝试删除事件侦听器。我想知道是否在基于生命周期的验证中使用了正确的验证器
这完全取决于您的总体Spring配置和使用 在DonorTypeExistsConstraintValidator上有@Component注释吗
在过去,这让我丧命。您是否通过JPA在执行验证时使用的验证程序工厂:
<bean
id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="jpaPropertyMap">
<map>
<entry
key="javax.persistence.validation.factory"
value-ref="validator"/>
<!-- ... -->
</map>
</property>
<!-- ... -->
</bean>
这是必需的,因为否则JPA将使用默认工厂(如validation.xml中所指定的)。LocalValidatorFactoryBean没有什么好运气。为了解决这个问题,我做了一些尝试
@Component
public class ServiceUtils
{
private static ServiceUtils instance;
@Autowired
private ListableBeanFactory factory;
@PostConstruct
public void init()
{
instance = this;
}
public static ListableBeanFactory getFactory()
{
return instance.factory;
}
}
哪个包是DonorTypeExistsConstraintValidator类,还显示包扫描配置。配置中是否包含或包含AutowiredNotationBeanPostProcessor@因为我无法理解对那个问题的回答。我上周没做那件事就让它正常工作了。但是现在它不起作用了。恢复到旧的提交太麻烦了。从那时起,我的模型和UI中发生了很多变化。因此,请查看代码中显而易见的内容。感谢您的回复。我为这个问题补充了更多的信息。我正在使用JPA,但我不确定我是否理解你的观点。为什么我应该禁用验证?我不是说
@Component
public class ServiceUtils
{
private static ServiceUtils instance;
@Autowired
private ListableBeanFactory factory;
@PostConstruct
public void init()
{
instance = this;
}
public static ListableBeanFactory getFactory()
{
return instance.factory;
}
}