为什么Hibernate验证器不关心@Valid,而仅关心@notnull?

发布于 2025-01-19 23:25:36 字数 3265 浏览 3 评论 0 原文

我正在尝试检查约束,看起来像这样。

class Registration {

    @Valid
    @NotNull
    private User user;
}

class User {

    @NotBlank
    private String name;

    @Max(128)
    @Min(0)
    @PositiveOrZero
    private int age;
}

当我尝试调用 iSvalidfor(registration.class,“用户”,null)时,它会填充一个非空的 set< condraintaintviolation< registration> ,如预期的。

但是它返回 iSvalidfor(registration.class,“用户”,< Invalid用户>)的空集。

        final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
        final User user = User.newInstanceWithInvalidAge();
        Assertions.assertThat(validator.validate(user))
                .isNotEmpty(); // succeeds
        final BeanDescriptor constraints = validator.getConstraintsForClass(Registration.class);
        for (final PropertyDescriptor constrainedProperty
                : constraints.getConstrainedProperties()) {
            log.debug("constrained property: {}", constrainedProperty);
            for (final ConstraintDescriptor<?> constraintDescriptor
                    : constrainedProperty.getConstraintDescriptors()) {
                log.debug("\tconstraint descriptor: {}", constraintDescriptor);
            }
        }
        final Registration registration = Registration.builder().user(user).build();
        Assertions.assertThat(validator.validate(registration))
                .isNotEmpty(); // succeeds
        Assertions.assertThat(validator.validateValue(Registration.class, "user", user))
                .isNotEmpty(); // fails

这是它打印的东西。

constrained property: PropertyDescriptorImpl{
    propertyName=user,
    cascaded=true
}
constraint descriptor: ConstraintDescriptorImpl{
    annotation=j.v.c.NotNull,
    payloads=[],
    hasComposingConstraints=true,
    isReportAsSingleInvalidConstraint=false,
    elementType=FIELD,
    definedOn=DEFINED_LOCALLY,
    groups=[interface javax.validation.groups.Default],
    attributes={groups=[Ljava.lang.Class;@664a9613,
                message={javax.validation.constraints.NotNull.message},
                payload=[Ljava.lang.Class;@5118388b},
                constraintType=GENERIC,
                valueUnwrapping=DEFAULT
    }

为什么 iSvalidfor 方法不在乎 @valid

我正在努力以下依赖关系。

    <dependency>
      <groupId>javax.validation</groupId>
      <artifactId>validation-api</artifactId>
      <version>2.0.1.Final</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.glassfish</groupId>
      <artifactId>javax.el</artifactId>
      <version>3.0.1-b12</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.hibernate.validator</groupId>
      <artifactId>hibernate-validator</artifactId>
      <version>6.0.23.Final</version>
      <scope>test</scope>
    </dependency>

I'm trying to check constraints look like this.

class Registration {

    @Valid
    @NotNull
    private User user;
}

class User {

    @NotBlank
    private String name;

    @Max(128)
    @Min(0)
    @PositiveOrZero
    private int age;
}

When I try to invoke isValidFor(Registration.class, "user", null) it populates a non empty Set<ConstraintViolation<Registration>> as expected.

But it returns an empty set for isValidFor(Registration.class, "user", <invalid User>).

        final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
        final User user = User.newInstanceWithInvalidAge();
        Assertions.assertThat(validator.validate(user))
                .isNotEmpty(); // succeeds
        final BeanDescriptor constraints = validator.getConstraintsForClass(Registration.class);
        for (final PropertyDescriptor constrainedProperty
                : constraints.getConstrainedProperties()) {
            log.debug("constrained property: {}", constrainedProperty);
            for (final ConstraintDescriptor<?> constraintDescriptor
                    : constrainedProperty.getConstraintDescriptors()) {
                log.debug("\tconstraint descriptor: {}", constraintDescriptor);
            }
        }
        final Registration registration = Registration.builder().user(user).build();
        Assertions.assertThat(validator.validate(registration))
                .isNotEmpty(); // succeeds
        Assertions.assertThat(validator.validateValue(Registration.class, "user", user))
                .isNotEmpty(); // fails

Here comes what it prints.

constrained property: PropertyDescriptorImpl{
    propertyName=user,
    cascaded=true
}
constraint descriptor: ConstraintDescriptorImpl{
    annotation=j.v.c.NotNull,
    payloads=[],
    hasComposingConstraints=true,
    isReportAsSingleInvalidConstraint=false,
    elementType=FIELD,
    definedOn=DEFINED_LOCALLY,
    groups=[interface javax.validation.groups.Default],
    attributes={groups=[Ljava.lang.Class;@664a9613,
                message={javax.validation.constraints.NotNull.message},
                payload=[Ljava.lang.Class;@5118388b},
                constraintType=GENERIC,
                valueUnwrapping=DEFAULT
    }

Why the isValidFor method doesn't care for @Valid?

I'm working on following dependencies.

    <dependency>
      <groupId>javax.validation</groupId>
      <artifactId>validation-api</artifactId>
      <version>2.0.1.Final</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.glassfish</groupId>
      <artifactId>javax.el</artifactId>
      <version>3.0.1-b12</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.hibernate.validator</groupId>
      <artifactId>hibernate-validator</artifactId>
      <version>6.0.23.Final</version>
      <scope>test</scope>
    </dependency>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

坏尐絯 2025-01-26 23:25:36

我刚刚发现 @Valid 不被 validateProperty 方法所尊重。

<代码>设置> validateProperty(T object, String propertyName, Class... groups) 验证对象的给定字段或属性。当调用 validateProperty() 并且 object 为 null 或 propertyName 为 null、空或无效时,会引发 IllegalArgumentException或 null 被传递给 varargs groups 参数。属性名称是 JavaBeans 属性名称(由 JavaBeans Introspector 类定义)。此方法实现验证例程中描述的逻辑,但仅限于给定的属性。 @Valid 不受此方法的支持。此方法对于部分对象验证很有用。

我还是想知道为什么。

I just found the @Valid is not honored by the validateProperty method.

<T> Set<ConstraintViolation<T>> validateProperty(T object, String propertyName, Class<?>... groups) validates a given field or property of an object. An IllegalArgumentException is thrown when validateProperty() is called and object is null or propertyName is null, empty or invalid or null is passed to the varargs groups parameter. The property name is the JavaBeans property name (as defined by the JavaBeans Introspector class). This method implements the logic described in Validation routine but only to the given property. @Valid is not honored by this method. This method is useful for partial object validation.

I still want to know why.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文