小编典典

在自定义约束验证器中,自动装配的存储库为空

spring

我有一个基于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;
  }
}

更新资料

程序包扫描配置:

<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。这实际上与这里的建议相反: JSR-303依赖项注入和Hibernate

  @Override
  public void integrate(Configuration configuration, SessionFactoryImplementor implementor,
                        SessionFactoryServiceRegistry registry) {
      logger.info("Registering event listeners");
      System.out.println("here");
      // you can add duplication strategory for duplicate registrations

      final EventListenerRegistry eventRegistry = registry.getService(EventListenerRegistry.class);
      // prepend to register before or append to register after
      // this example will register a persist event listener

      eventRegistry.prependListeners(EventType.PERSIST, EntitySaveListener.class);
      eventRegistry.appendListeners(EventType.MERGE, EntitySaveListener.class);
      Iterator<PreInsertEventListener> iter = eventRegistry.getEventListenerGroup(EventType.PRE_INSERT).listeners().iterator();
      while (iter.hasNext()) {
        PreInsertEventListener el = iter.next();
        System.out.println(el.getClass());
        BeanValidationEventListener listener = (BeanValidationEventListener) el;
        System.out.println(listener);
        iter.remove();
      }
  }

阅读 320

收藏
2020-04-21

共1个答案

小编典典

你正在使用哪个ValidatorFactory。还是换一种说法,你对Bootstrap Bean验证很感兴趣?默认情况下,Bean验证(和Hibernate Validator作为参考实现)不会将依赖项注入ConstraintValidator实例中。至少在Bean Validation 1.0中。

为了启用依赖注入,你必须配置一个自定义ConstraintValidatorFactory。Spring提供SpringConstraintValidatorFactory,这是使用LocalValidatorFactoryBean时的默认设置-请参见http://static.springsource.org/spring/docs/3.0.0.RC3/reference/html/ch05s07.html

另外,你正在使用JPA吗?我假设是这样,在这种情况下,将自动对生命周期事件进行自动验证。无需尝试删除事件侦听器,你可以使用属性javax.persistence.validation.mode并将其设置为NONE。我想知道是否在基于生命周期的验证中使用了正确的验证器。

这完全取决于你的整体Spring配置和使用。

2020-04-21