Search code examples
hibernatevalidationbean-validationhibernate-validator

Hibernate validator - way to link annotation with validator


Is there any way to link validation annotation with custom validator except through @Constraint annotation?

Unique.java

@Documented
//----@Constraint(validatedBy = { UniqueValidator.class })----//
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface Unique {

    String message() default "org.hibernate.validator.constraints.Unique.message";

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

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

UniqueValidator.java

public class UniqueValidator implements ConstraintValidator<Unique, Object> {
    @Override
    public void initialize(Unique unique) {}

    @Override
    public boolean isValid(Object object, ConstraintValidatorContext constraintValidatorContext) {
    }
}

Solution

  • You always need the @Constraint annotation. It is the marker for Bean Validation that we have a constraint annotation. You can, however, use an empty validatedBy value:

    @Documented
    @Constraint(validatedBy = { })
    @Target({ ElementType.TYPE })
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Unique {
    
        String message() default "org.hibernate.validator.constraints.Unique.message";
    
        Class<?>[] groups() default {};
    
        Class<? extends Payload>[] payload() default {};
    }
    

    If you leave validatedBy empty you have two options. If you want to stick to use Bean Validation features, you can use XML configuration via a constraint mappings file (listed in validation.xml)

    <constraint-mappings
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.1.xsd"
        xmlns="http://jboss.org/xml/ns/javax/validation/mapping" version="1.1">
        ...
        <constraint-definition annotation="com.acme.Unique">
            <validated-by include-existing-validators="false">
                <value>com.acme.UniqueValidator</value>
            </validated-by>
        </constraint-definition>
    

    Hibernate Validator 5.2 also offers a provider specific feature to add constraint definitions. Have a look at ConstraintDefintionContributor - http://docs.jboss.org/hibernate/validator/5.2/reference/en-US/html_single/#section-constraint-definition-contribution. Either you provide your own contributor at bootstrap or you can even use the Java ServiceLoader mechanism and just add a META-INF/services/javax.validation.ConstraintValidator listing your ConstraintValidator implementations.