Java 自定义约束验证程序中的自动连线存储库为空

Java 自定义约束验证程序中的自动连线存储库为空,java,spring,hibernate,validation,bean-validation,Java,Spring,Hibernate,Validation,Bean Validation,我有一个基于Spring的webapp。我在控制器中使用了几个带有注释@repository、@Transactional的存储库类。那部分很好用 我创建了一个自定义约束验证器,它必须访问存储库。现在我无法理解为什么存储库为空。我尝试用@Component注释验证程序。包含所有这些类的基本包位于xml部分。那么,我还应该做些什么来确保存储库依赖项注入工作呢。这就是我的约束验证器的样子 public class DonorTypeExistsConstraintValidator implemen

我有一个基于Spring的webapp。我在控制器中使用了几个带有注释@repository、@Transactional的存储库类。那部分很好用

我创建了一个自定义约束验证器,它必须访问存储库。现在我无法理解为什么存储库为空。我尝试用@Component注释验证程序。包含所有这些类的基本包位于xml部分。那么,我还应该做些什么来确保存储库依赖项注入工作呢。这就是我的约束验证器的样子

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;
    }
}