我有一个基于 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 dependency injection and 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();
}
}
更新
我正在使用 JPA。我有 JPA 实体的支持表格。在控制器中,我使用 InitBinder 来实例化自定义验证器binder.setValidator(new EntityBackingFormValidator(binder.getValidator()));
。这是代码:
https ://github.com/C4G/V2V/blob/87dc266043f6d623c101d947a88fa0b0ad536355/src/controller/CollectedSampleController.java
此自定义验证器调用默认验证器上的验证,并保留执行一些自定义验证的范围。 https://github.com/C4G/V2V/blob/87dc266043f6d623c101d947a88fa0b0ad536355/src/model/collectedsample/CollectedSampleBackingFormValidator.java
我在实体中使用注释来创建约束。除了默认约束之外,我还需要定义约束来检查多对一映射另一侧的实体是否存在。这是自定义约束验证器。 https://github.com/C4G/V2V/blob/87dc266043f6d623c101d947a88fa0b0ad536355/src/model/donor/DonorExistsConstraintValidator.java
现在,此自定义约束验证器中的自动装配存储库为空。我正在尝试在我的 CustomIntegrator 中自定义代码,该代码位于此处 https://github.com/C4G/V2V/blob/87dc266043f6d623c101d947a88fa0b0ad536355/src/interceptor/CustomIntegrator.java
以及此处提供的 xml 配置文件 https://github.com/C4G/V2V/blob/87dc266043f6d623c101d947a88fa0b0ad536355/war/WEB-INF/v2v-servlet.xml
希望实际代码能帮助您回答我的问题。谢谢!