Как добавить несколько нарушений ограничений для одного и того же узла свойств? - PullRequest
0 голосов
/ 28 февраля 2020

У меня есть кастом ConstraintValidator. Что я хочу сделать, так это добавить несколько нарушений ограничений для одного и того же узла свойства, с одним и тем же сообщением и разными динамическими c полезными данными. Возможно ли это?

Пользовательская аннотация:

@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 {};
}

Пользовательский валидатор ограничений:

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;
    }
}

Тест валидатора:

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>.

1 Ответ

0 голосов
/ 29 февраля 2020

Эта проблема возникает из-за того, что ConstraintViolation возвращаются в виде набора, а по умолчанию динамическая полезная нагрузка c не включена в метод equals(). См. https://github.com/hibernate/hibernate-validator/blob/master/engine/src/main/java/org/hibernate/validator/internal/engine/ConstraintViolationImpl.java#L251.

Таким образом, ваши 2 ограничения считаются равными на уровне набора.

Вам необходимо изменить способ работы и обогатить полезную нагрузку с помощью обоих вместо информации.

...