Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 727
Marcel Overdijk Avatar asked May 18 '14 18:05

Marcel Overdijk


People also ask

What is ConstraintViolation in Java?

public interface ConstraintViolation<T> Describes a constraint violation. This object exposes the constraint violation context as well as the message describing the violation.

What is constraint violation?

A constraint violation is simply a grammatical error or a value that does not adhere to the LDAP schema. For example , you may be creating a user and providing characters that are not allowed for an attribute. Example: The telephone number attribute has schema that allows only numbers.

How do you validate a constraint?

The VALIDATE CONSTRAINT statement is part of ALTER TABLE and checks whether values in a column match a constraint on the column. This statement is especially useful after applying a constraint to an existing column via ADD CONSTRAINT .


2 Answers

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.

like image 99
Hardy Avatar answered Sep 21 '22 10:09

Hardy


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.

like image 32
Makoto Avatar answered Sep 22 '22 10:09

Makoto