【问题标题】:@Valid and custom validation annotation - when does validation take place?@Valid 和自定义验证注解 - 何时进行验证?
【发布时间】:2015-10-02 06:41:00
【问题描述】:

我开发应用程序,发现一些我无法理解的东西。 我创建了名为 @UsernameAvailable 的自定义验证注释和 ConstraintValidator 的实现。

我用注释注释了我的实体的某些字段,并添加了一些 System.out.println("something message");在 ConstraintValidator isValid() 方法中。

我注意到验证方法被调用了两次:

一开始页面上的表单被提交并且数据被绑定到实体。 然后,第二次当实体被 JpaRepository(来自 Spring Data JPA)保存时

但不同之处在于,在我的 ConstraintValidator 实现中,我有一些 @Autowired 依赖项,并且当第一次在“表单提交验证”上进行验证时,依赖项被正确注入。

第二次,在保存实体时调用 isValid 方法,我的 @Autowired Service 为空,这是为什么呢?

如果您不明白,请阅读并观看:

我写的所有内容都显示在此视频中:https://www.youtube.com/watch?v=rFf0CaxaHVc(最好,从 04:20 分钟开始观看)

这正是我遇到的问题,为什么我必须检查 isValid 中的空值?为什么服务为空?

理解这一点对我来说很重要

【问题讨论】:

    标签: java spring validation jpa


    【解决方案1】:

    我在 Java EE (JSF/CDI/EJB/JPA) 应用程序中遇到了同样的问题。我认为这里发生的事情完全一样。

    您有两个在此处执行验证的不同容器。从提交表单的位置(在我的情况下是 CDI 托管 bean),以及在 JPA 在持久化之前创建和调用验证器时从 ejb 内部提交。

    对于表单验证,容器会创建一个支持注入的验证器。但是,在表单验证之后,实体将被提交到 ejb 服务(在您的情况下可能会有所不同),该服务进而调用 JPA/EntityManager 来持久化等。JPA 在持久化之前有一个验证步骤,但不会创建这样的验证器(具有 CDI 功能),因此任何注入尝试都会失败,如您所见。 JPA 规范中没有要求在验证步骤中支持注入,我已经使用 eclipseLink 和 Hibernate 进行了测试。

    将有几个选项可以解决这个问题 - 但似乎没有一个选项比让 JPA 支持具有 CDI 功能的自定义验证器更优雅 - 至少在您的场景中是这样。因此,出于此答案的目的,我可以确认您观察到的行为当前是由于给定的原因而指定/设计的。 我在这里遇到了同样的问题EJB injection fails in custom ConstraintValidator on JPA persist

    【讨论】:

    • 谢谢!所以你说在坚持之前有一个验证步骤。有没有办法禁用它?在表单提交上验证 bean 之后,什么都不会发生,所以对我来说已经足够了。顺便说一句,多么奇怪,为什么所有的验证器都不能支持注入?:) 他们应该
    • @azalut - 尝试将 NONE 添加到您的 persistence.xml。不知道为什么不支持。祝你好运。
    猜你喜欢
    • 2014-09-24
    • 2018-10-25
    • 2011-06-13
    • 2021-12-29
    • 1970-01-01
    • 1970-01-01
    • 2018-03-14
    • 2017-03-02
    相关资源
    最近更新 更多