java - 如何为同一个属性节点添加多个约束违规?

标签 java hibernate-validator

我有一个自定义ConstraintValidator 。我想要做的是使用相同的消息和不同的动态负载为同一属性节点添加多个约束违规。这可能吗?

自定义注释:

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = CustomFieldConstraintValidator.class)
public @interface CustomFieldConstraint {
    String message() default "message";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

自定义约束 validator :

public class CustomFieldConstraintValidator implements ConstraintValidator<CustomFieldConstraint, Integer> {
    @Override
    public boolean isValid(Integer value, ConstraintValidatorContext context) {
        var valid = true;
        var hibernateConstraintValidatorContext = context.unwrap(HibernateConstraintValidatorContext.class);
        hibernateConstraintValidatorContext.disableDefaultConstraintViolation();

        if (value > 0) {
            valid = false;

            hibernateConstraintValidatorContext.withDynamicPayload(Map.of("must_be_less_than", 0))
                .buildConstraintViolationWithTemplate(context.getDefaultConstraintMessageTemplate())
                .addPropertyNode("field")
                .addConstraintViolation();
        }

        if (value > 5) {
            valid = false;

            hibernateConstraintValidatorContext.withDynamicPayload(Map.of("must_be_less_than", 5))
                .buildConstraintViolationWithTemplate(context.getDefaultConstraintMessageTemplate())
                .addPropertyNode("field")
                .addConstraintViolation();
        }

        return valid;
    }
}

validator 测试:

public class HibernateValidatorTest {
    private final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

    @Test
    void multipleFailuresForSameField() {
        var foo = new Foo(10);

        var constraintViolations = validator.validate(foo);

        assertEquals(2, constraintViolations.size());
    }

    public static class Foo {
        @CustomFieldConstraint
        private int field;

        public Foo(int field) {
            this.field = field;
        }
    }
}

测试失败,并显示 expected: <2> but was: <1> .

最佳答案

您遇到此问题的原因是 ConstraintViolation 作为一组返回,并且根据设计,动态负载不包含在 equals() 方法中。请参阅https://github.com/hibernate/hibernate-validator/blob/master/engine/src/main/java/org/hibernate/validator/internal/engine/ConstraintViolationImpl.java#L251 .

因此,您的 2 个约束在集合级别被认为是相等的。

您需要改变做事的方式,并用这两种信息来丰富有效负载。

关于java - 如何为同一个属性节点添加多个约束违规?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60457038/

相关文章:

java - macOS Mojave (10.14) 到 Lion (10.7) 上的 JAVA_HOME 在哪里?

java - Eclipse 中 token 的语法错误

java - Java中私有(private)静态变量有什么用?

hibernate - 如何使用 Hibernate 配置自定义消息插值?

java - 继承类的Spring MVC验证

java - 获取 YAML 路径下的所有节点

java - 正确使用 GridBagLayout 设计面板

java - 如何使用 hibernate 将数字字符串验证为数字?

validation - Spring 框架 <form :errors/> tag not showing errors

java - ConstraintViolationException 处理程序未在 Micronaut 中执行