Search code examples
springibatisbean-validationmybatis

JSR-303 bean validation with Spring and iBatis


Is it possible with JSR-303 bean validation to write a custom annotation that can talk to a back end service?

We accomplished this type of validation with the "old school" Spring validators. In that case, the validator was a Spring bean and could have other services injected into it. Then that validator is injected into the controller.

An example might be an annotation (perhaps @EmailExists) to verify if an email already exists. I can only do this with a SQL query using one of our services. I would prefer to "validate" this alongside the other annotations and check it as soon as possible and not have to explicity do it in a back end service.

NOTE: We are using iBatis/MyBatis so I can't use any JPA/Hibernate tricks :-)

thanks!


Solution

  • That's definitely possible. Spring provides dependency injection support also within constraint validators. So you can simply inject any required services in your custom validators like this:

    public class EmailExistsValidator implements ConstraintValidator<EmailExists, String> {
    
        @Inject
        private EmailValidationService service;
    
        @Override
        public void initialize(EmailExists constraintAnnotation) {}
    
        @Override
        public boolean isValid(String value, ConstraintValidatorContext context) {
    
            if (value == null) {
                return true;
            }
    
            return service.exists(value);
        }
    }
    

    Depending on your concrete scenario it might be a good idea to first check "cheap" constraints such as @NotNull and only if these constraints are valid check more expensive constraints such as @EmailExists.

    You can do this with help of group sequences and a redefined default group sequence for your type.