Marcel Overdijk
Marcel Overdijk

Reputation: 11467

Adding constraint violation manually

Is it possible to add constraint violation manually?

E.g.:

// validate customer (using validation annotations)
Set<ConstraintViolation<Customer>> violations = validator.validate(customer);

if (someSpecialCase) {
    violations.add(..) 
}

The problem is the add method accepts a ConstraintViolation interface but the javax.validation package contains no implementors that can be used.

Any idea?

Upvotes: 8

Views: 18697

Answers (2)

Hardy
Hardy

Reputation: 19109

The short answer is: "No, there is no way to manually add constraint violations".

To elaborate a little bit. As you say, all classes involved are interfaces. If you really think you want to do it, you could implement your custom ConstraintViolationImpl. However, I am wondering what your actual use case is? Why do you want to add a constraint violation without validation? As the answer https://stackoverflow.com/a/23727169/115835 suggest, you could always go via a class level custom constraint. As part of isValid in your custom ConstraintValidator implementation, you get an ConstraintValidatorContext which will allow you to add additional constraint violations.

Upvotes: 3

Makoto
Makoto

Reputation: 106390

I believe that you're using Hibernate validators for this.

If that's the case, then depending on the special case you have, you would want to write a custom class-level validator for a Customer instead, and let it be captured in the set of constraint violations.

Since I don't know what your Customer bean looks like, I can only at best offer you a general direction on this approach.

// Annotation
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Constraint(validatedBy = CustomerValidator.class)
public @interface ValidCustomer {
    String message() default "Invalid customer (due to edge case)";
    Class<?>[] groups() default { };
    Class<? extends Payload>[] payload() default { };
}

// Validator

public class CustomerValidator implements ConstraintValidator<ValidCustomer, Customer> {

    @Override
    public void initialize(final ValidCustomer constraintAnnotation) {

    }

    @Override
    public boolean isValid(final Customer value,
                           final ConstraintValidatorContext context) {
        // logic for validation according to your edge case
    }
}

You would then annotate your Customer class with this validator.

@ValidCustomer
public class Customer {
    // ...
}

After this, your specific constraint will be captured in violations.

Upvotes: 4

Related Questions