Trifork Blog

Bean Validation: Integrating JSR-303 with Spring

August 4th, 2009 by
|

I recently had a chance to actually use the new Bean Validation spec. in one of my projects. As the developer of the Bean Validation Framework for Spring (part of the springmodules project) it of course feels a bit weird to ditch all the work I’ve done, but at the same time, it also feels good to use a standard spec that very soon will be finalized. As a member of the JSR-303 expert group (although quite a quiet member) I can assure you that the guys (special kudo’s to Emmanuel Bernard) worked really hard to come up with a specification that will fit in many of the different programming models and technologies we all use (e.g. JPA, JSF, Swing, etc..). In this writing, I’d like to show you a how you can integrate Bean Validation in your Spring based application, especially  if you’re using Spring MVC. Please note, that Spring 3.0 promises to bring such support out of the box, but the last time I checked, it wasn’t implemented yet, and besides, if you’re using Spring 2.x you may find this useful as well.

JSR-303

JSR-303 is a specification for Bean Validation. The work on it started around one and a half years ago as an attempt to come up with a standard declarative validation framework. With Java 5 release and the introduction of annotations, more and more framework developers realized the potential of declarative validation. WebWork had it, Hiberante came up with the Hibernate Validator framework, and I developed such support for spring. We all had the same idea’s, we all shared the same points of views and it was just a matter of time until this would be standardized.

The goal of this specification is not to provide one solution to fit all your validation needs – not at all. There are many types of constraints in an application that span different layers. Data constraints on the database level, business rules on the service level, and even UI constraints purely on the UI level. JSR-303 target what I like to refer to as the model constraints. The idea is very simple – some constraints on your model are tightly coupled to it and therefore belongs next to it. The infrastructure defined by JSR-303 enables you to do that – you can describe the constraints using constraint annotations on your model and validate your model using constraint validators.

As in most cases, an example works best, so let’s look at one. Consider having a class representing an email message with the following constraints:

  • The from property should not be empty and represent an email
  • The to property should not be empty and represent an email
  • The subject is not empty
  • The body is not empty

Here is how you can model it as a java bean and define these constraints:

public class Email {

    @NotEmpty @Pattern(".+@.+\\.[a-z]+")
    private String from;

    @NotEmpty @Pattern(".+@.+\\.[a-z]+")
    private String to;

    @NotEmpty
    private String subject;

    @NotEmpty
    private String body;

    // setters and getters
    ...
}

NOTE: it is possible to put the annotations on the fields or on the setter methods of the bean properties. Personally I like putting them on the fields as it’s easier to pick up when reading the code.

Here’s the code that actually validates an email object based on these constraints:

Email email = new Email();
email.setFrom("john@domain.com");
email.setTo("someone");
email.setSubject("");
email.setBody(null);

ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
Validator validator = validatorFactory.getValidator();

Set<ConstraintViolation<Email>> violations = validator.validate(email);
for (ConstraintViolation<Email> violation : violations) {
    String propertyPath = constraintViolation.getPropertyPath().toString();
    String message = constraintViolation.getMessage();
    System.out.println("invalid value for: '" + propertyPath + "': " + message);
}

In lines 1-5 we construct the email object and initialize it with invalid data (the to property does not represent a valid email, the subject is empty and the body is null). In lines 7-8 the Validator is created using the default ValidatorFactory. And finally, in lines 10-15, we perform the validation and iterate over the constraint violations that the validator generated.

Spring Validation

Spring has its own mechanism to do validation. It is not declarative but very flexible and extensible. It is mostly used in SpringMVC to preform validation of command object that are bound to request parameters before they are sent to the controllers. In spring the main validation construct is the Validator interface:

public class Validator {

    boolean supports(Class type);

    void validate(Object target, Errors errors);

}

The supports method indicates whether the validator can validate a specific class. If so, the validate method can be called to validate an instance of that class. The implementation of this method can then register any validation errors that it encounters with the passed in Errors instance.

Although spring doesn’t come with any default implementation of this interface, it does comes with the ValidationUtils class which provides a few helper methods to perform some common validations. Here is the same example as above, but this time the validation is done using a Spring Validator:

public class EmailValidator implements Validator {

    private final static Pattern EMAIL_PATTERN = Pattern.compile(".+@.+\\.[a-z]+");

    public boolean supports(Class type) {
        return Email.class.equals(type);
    }

    public void validate(Object target, Errors errors) {
        Email email = (Email) target;

        String from = email.getFrom();
        if (!StringUtils.hasText(from)) {
            errors.rejectValue("from", "required");
        } else if (!isEmail(from)) {
            errors.rejectValue("from", "invalid.email");
        }

        String to = email.getTo();
        if (!StringUtils.hasText(to)) {
            errors.rejectValue("from", "required");
        } else if (!isEmail(to)) {
            errors.rejectValue("from", "invalid.email");
        }

        ValidationUtils.rejectIfEmpty(errors, "subject", "required");
        ValidationUtils.rejectIfEmpty(errors, "body", "required");
    }

    private boolean isEmail(String value) {
        return EMAIL_PATTERN.matcher(value).matches();
    }
}

Now that we’ve defined the validator, we can perform the validation as follows:

Email email = new Email();
email.setFrom("john@domain.com");
email.setTo("someone");
email.setSubject("");
email.setBody(null);

BindException errors = new BindException("email", email);
EmailValidator validator = new EmailValidator();
validator.validate(email, errors);

for (FieldError error : (List<FieldError>) errors.getFieldErrors()) {
    System.out.println("invalid value for: '" + error.getField() + "': " + error.getDefaultMessage());
}

Enjoy both worlds

As you can see, declarative validation is much more elegant, expressive, and in general simpler to use when compared to the classic Spring valiator way. On the other hand, the spring validation mechanism is well integrated in Spring MVC and if you’re using it for your web development, you probably want to take advantage of that. So what we’re really looking for is a way to enjoy both worlds. Luckily, due to the extensible nature of the Spring validation mechanism, we can easily get there. The idea is to simply create a spring validator implementation which delegates the validation tasks to the JSR-303 validator. So let’s do that:

First you’ll need to get a hold of the latest version of the reference implementation for JSR-303. You can either download the following jars manually:

http://repository.jboss.com/maven2/javax/validation/validation-api/1.0.CR3/validation-api-1.0.CR3.jar

http://repository.jboss.com/maven2/org/hibernate/hibernate-validator/4.0.0.Beta2/hibernate-validator-4.0.0.Beta2.jar

Or, if you’re using maven (like me) you can just add the following to your pom:

<repositories>
    <repository>
        <id>jboss</id>
        <url>http://repository.jboss.com/maven2</url>
        <releases>
            <enabled>true</enabled>
        </releases>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>

<dependencies>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>4.0.0.Beta2</version>
    </dependency>
</dependencies>

Assuming you have your project setup already and spring configured, let’s look at the BeanValidator implementation:

public class BeanValidator implements org.springframework.validation.Validator, InitializingBean {

    private Validator validator;

    public void afterPropertiesSet() throws Exception {
        ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
        validator = validatorFactory.usingContext().getValidator();
    }

    public boolean supports(Class clazz) {
        return true;
    }

    public void validate(Object target, Errors errors) {
        Set<ConstraintViolation<Object>> constraintViolations = validator.validate(target);
        for (ConstraintViolation<Object> constraintViolation : constraintViolations) {
            String propertyPath = constraintViolation.getPropertyPath().toString();
            String message = constraintViolation.getMessage();
            errors.rejectValue(propertyPath, "", message);
        }
    }
}

Since the validation framework can potentially validate any object, the supports method return true to all types. Also notice that the bean validator is actually created at load time. This is fine as according to the spec. a Validator instance must be thread safe – this means that we can register this BeanValidator as a singleton in the application context and reuse it in all our controllers. All the validate method does is translate the constraint violations to error messages which are registered with the passed in errors instance.

Now that we have the BeanValidator ready, all that is required in order to use it is to register it in the application context. If you’re using spring’s component-scaning mechanism, you can simply annotate it with the @Component annotation, otherwise you can just add the following line to your application context configuration:

<bean id="beanValidator" class="package.name.BeanValidator"/>

Done! You can now inject this validator to all your SpringMVC controllers and benefit from the JSR-303 declarative validation.

Writing you own custom constraints

JSR-303 defines a set of constraints that should be supported out of the box by all providers. But this is a relatively limited set and when developing real world application you’ll probably find the need to extend it and provide your own custom constraints. There are two ways of doing this – write it from scratch or combine a constraints from other already existing constraints.

Writing from scratch

To write a new constraint from scratch you first need to know how JSR-303 constraints work.

A constraint is basically a pair of an annotation and its associated validator class. When a bean is validated, it is being scanned for all the constraint annotations. Once such annotation is found its associated validator is created and initialized with the annotation (the annotation in a way serves as the configuration for its validator). How does the framework know which validator to instantiate? well… the annotation indicates it, and it’s best explained by an example.

In the first example above, we showed how one can validate an email using the @Pattern annotation. It would be much more expressive (and semantically right) if we would have an @Email annotation instead which would also relieve us from remembering the email regular expression each time we need to apply this constraint. To make it work we’ll first define the @Email annotation:

@Documented
@Constraint(validatedBy = EmailValidator.class)
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface Email {

    public abstract String message() default "{package.name.Email.message}";

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

    public abstract Class<? extends ConstraintPayload>[] payload() default {};

}

All the defined attributes in this annotation are specified in the spec. and mandatory for all constraint annotations. I will not discuss the payload and groups attributes but the message attribute defines the error message that should be used in case the constraint is violated. Beside these mandatory attributes, each constraint annotation can define additional attributes as needed. In our example, there no such need, but a @Range annotation for example, which can be used to define the boundaries of an integer value, will probably define a min and a max attributes.

NOTE: The specification define quite a powerful message interpolation mechanism for the error messages. The message can contain placeholders (surrounded by curly brackets) which can be replaced by the attributes defined in the annotation itself. Furthermore, the placeholders can also refer to keys defined in a resource bundle. In the later case the placeholders will be replaced by their associated values in the bundle. For example, as we did in the @Email annotation, it is considered a best practice to assign a default message value. This value actually consists of one parameter placeholder which refers to a key in a resource bundle (“package.name.Email.message“). When the error message is resolved, the value of this key is looked up in the resource bundle and when found replaces the placeholder. By default, the validator will look for a resource bundle named ValidationMessages.properties in the classpath.

Notice that the @Email annotation itself is annotated with a @Constraint annotation. This annotation indicates that @Email is a constraint. The validatedBy attributes indicates the validator class which should be used to validate the constraint. This is how the bean validator knows which constraint validator class to instantiate. Let’s look at the EmailValidator class:

public class EmailValidator implements ConstraintValidator<Email, String> {

    private final static Pattern EMAIL_PATTERN = Pattern.compile(".+@.+\\.[a-z]+");

    public void initialize(Email constraintAnnotation) {
        // nothing to initialize
    }

    public boolean isValid(String value, ConstraintValidatorContext context) {
        return EMAIL_PATTERN.matcher(value).matches();
    }
}

The first thing to note about this class is that it implements the ConstraintValidator interface. This interface accepts two generic types – the first indicates the annotation it is associated with (@Email in our case) and the second indicates the type of objects it can validate (String in our case).

The initialize method (line 5) is called after the constraint validator is instantiated. The constraint annotation is passed in as the configuration. Continuing the @Range example from above, a RangeValidator will probably extract the min and max values from the annotation which will later be used to perform the actual range validation.

The isValid method (line 9) does the actual validation. This is where you need to put the validation logic, which in our case, is just matching the string to an email regular expression.

The only thing that is left to do, is to create a ValidationMessage.properties file and put it in the classpath. This is the user defined resource bundle that the bean validator work with by default. Now, add the default error message code to it to provide a default user friendly message:

package.name.Email.message=Invalid email

Thats it, you’re done. You can change the original code of our email example to use this new annotation (instead of the @Pattern annotation) and see it in action.

Composing annotations

Sometimes there is no real need to create constraint entirely from scratch. It is often the case where a constraint is either a specific variation of another constraint, or a combination of other finer grained constraints. The specification acknowledges that and makes it even easier to define such constraints.

Take the @Email constraint for example. Instead of creating a validator for it, we can also view this constraint as a narrowed version (or a specific case) of the @Pattern constraint. So we can actually compose it instead of creating from scratch.

In order to compose an annotation, all that is needed is to annotate the new constraint annotation with the constraint annotations that compose it. hmmm… confuse? well, an example will clear it up. Here is the @Email annotation again, yet this time it is composed of the standard @Pattern annotation:

@Documented
@Constraint(validatedBy = {})
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Pattern(regexp = ".+@.+\\.[a-z]+")
@ReportAsSingleViolation
public @interface Email {

    public abstract String message() default "{package.name.Email.message}";

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

    public abstract Class<? extends ConstraintPayload>[] payload() default {};

}

As you can see, no validator is associated with this annotation. Instead, it is annotated with the @Pattern annotation which holds the email regular expression. By default, when the validation is performed, all the composing constraints are evaluated (in our case, the @Patterm constraint) and register any encountered violations. It is sometimes (if not often) the case where you’d like only one error message to be reported – in our case, an “invalid email” message (not a “pattern mismatch” message). This is where the @ReportAsSingleViolation annotation becomes useful. This annotation indicates that on any constraint violation of any of the composing constraints, only one violation will be reported and it is of the composed constraint – all the other reported violations of the composing annotations will then be ignored.

Loading constraint validators from spring

As you’ve seen, the default implementation of the Validator instantiates the ConstraintValidators via reflection. Although good enough for most cases, sometimes the validation logic requires interaction with external services (for example, finding out whether a username is unique in the system). If you have this requirement and you’re using spring, you probably want these services to be injected into the validator, and in fact, let spring instantiate the validator all together. To achieve that you’ll need to modify the BeanValidator implementation a bit:

public class BeanValidator implements org.springframework.validation.Validator,
        InitializingBean, ApplicationContextAware, ConstraintValidatorFactory {

    private Validator validator;

    private ApplicationContext applicationContext;

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public void afterPropertiesSet() throws Exception {
        ValidatorFactory validatorFactory = Validation.byDefaultProvider().configure()
                .constraintValidatorFactory(this).buildValidatorFactory();
        validator = validatorFactory.usingContext().getValidator();
    }

    public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) {

        Map beansByNames = applicationContext.getBeansOfType(key);
        if (beansByNames.isEmpty()) {
            try {
                return key.newInstance();
            } catch (InstantiationException e) {
                throw new RuntimeException("Could not instantiate constraint validator class '" + key.getName() + "'", e);
            } catch (IllegalAccessException e) {
                throw new RuntimeException("Could not instantiate constraint validator class '" + key.getName() + "'", e);
            }
        }
        if (beansByNames.size() > 1) {
            throw new RuntimeException("Only one bean of type '" + key.getName() + "' is allowed in the application context");
        }
        return (T) beansByNames.values().iterator().next();
    }

    public boolean supports(Class clazz) {
        return true;
    }

    public void validate(Object target, Errors errors) {
        Set<ConstraintViolation<Object>> constraintViolations = validator.validate(target);
        for (ConstraintViolation<Object> constraintViolation : constraintViolations) {
            String propertyPath = constraintViolation.getPropertyPath().toString();
            String message = constraintViolation.getMessage();
            errors.rejectValue(propertyPath, "", message);
        }
    }

As you can see, out BeanValidator now implements two additional interfaces. The first is Spring’s ApplicationContextAware interface. This will cause the application context to be injected into the validator. The second interface is the ConstraintValidationFactory. It is a JSR-303 interface which abstract the way the constraint validators are constructed. In our case, we first try to find a bean in the application context that matches the type of the constraint (lines 20-29). If none is found, we just instantiate the constraint class using reflection. Otherwise, we make sure that there’s only one bean definition of the constraint class and if so, it is returned (lines 30-33). The last change we needed to make in order for it to work is to configure the validator factory to use the new constraint validator factory. You can see how this is done at lines 13-14. Now, if your constraint validator requires other services, just add it to the application context, configure its dependencies and you’re done.

Conclusion

Well, that’s it for this entry. I tried to introduce you to the new JSR-303 bean validation specification and show you how you can already work and integrate with your spring applications. You have to remember though, that this spec is still undergoing some last changes and is not final yet (though personally, I don’t expect to see any major changes in the final version).

For me, although it’s not final yet and although the reference implementation is still in beta, I already feel comfortable using it in a real world project. Yes, there might be some bugs (they are fixed pretty quickly once reported), and I might need to change a few little things when the final release is out, but at the same time, I benefit from cleaner code that confirms to the standards and it always makes me happy when my projects are up to date with the latest and greatest technologies out there.

33 Responses

  1. August 5, 2009 at 04:53 by donny

    Thanks for the post!! 😀

  2. August 13, 2009 at 15:47 by Christoph

    Thanks for the post!

    What do you do if you want to inject a DAO or something else by Spring into the JSR-303 custom validator?
    Actually I am trying to implement it but I haven’t found a working solution yet?

    Any ideas or suggestions?

    Regards,
    Christoph

  3. August 14, 2009 at 03:12 by Uri Boness

    Hi Christoph,

    I added another section (at the bottom of the post, just before the conclusion) that addresses your issue.

    cheers,
    Uri

  4. August 14, 2009 at 15:03 by Christoph

    Hi Uri,

    thanks for your quick reply!

    My case is slightly different than yours. I would like to use HibernateValidation with RichFaces. My custom ConstraintValidatorFactory shall be initialised by Spring so I can inject i.e. DAOs.
    Unfortunately

    ValidatorFactory validatorFactory = Validation.byDefaultProvider().configure()
    .constraintValidatorFactory(this).buildValidatorFactory();
    validator = validatorFactory.usingContext().getValidator();

    does not seem to affect the standard way to get a validator

    Validation.buildDefaultValidatorFactory().getValidator();

    Maybe I’m totally wrong, but I would like to set my custom ConstraintValidator as default ConstraintValidator so RichFaces (and of course my tests) get a validator with a DAO.

    Do I have a complete misunderstanding of the HibernateValidators?

    Have a nice weekend,
    Christoph

  5. August 17, 2009 at 15:42 by Uri Boness

    Hi Christoph,

    I’m not familiar with the inner working of RickFaces and I’m not sure if I understand it correctly, but as far as I do, you don’t have control over the construction of the ValidatorFactory and RichFaces uses Validation.buildDefaultValidationFactory() by default, is that right? If that’s the case, then I think you have a problem.

    The only thing that is possible (I think) is to use another validation provider all together. You see, under the hood the the default validation provider is resolved the same way XML parsers are resolved by Java – using files entries in the META-INF/services directory in the classpath. But since you’re using RichFaces, the Hibernate provider will always be there I guess, and once you have multiple providers it’s hard to determine which one will be picked up.

    What I would suggest you to do is see if it is possible after all to control the ValidatorFactory construction, and if not then contact the RichFaces guys to ask for their help.

    But again, perhaps I got you completely wrong and this (again) doesn’t answer your question.

    Cheers,
    Uri

  6. August 19, 2009 at 14:44 by Christoph

    Hi Uri,

    thanks for your reply.

    I managed to get Hibernate Validators working with Spring and Richfaces. The “trick” is to have a custom constraint factory which is able to look up the Spring application context. In the Spring context there are all custom validators defined with the injected DAOs.

    You are right, Richfaces seem to use Validation.buildDefaultValidatorFactory().getValidator();

    The only working solution for me to set my custom validator factory as default validator factory was to configure /META-INF/validation.xml properly.

    Your help led me on the right way. Thanks a lot!

    Regards,
    Christoph

  7. August 20, 2009 at 20:50 by Uri Boness

    Hi Christoph,

    Glad to be of some help… and thanks for the feedback.

    cheers,
    Uri

  8. September 10, 2009 at 13:06 by Javed Mandary

    Thanks for this article .

    Just had a question though assuming that you have implemented the Email constraint e.g into an EmailConstraintValidator class and you wanted to inject a bean inside this EmailConstraintValidator how would you achieve this ?

    Am trying to do this in my Validator class by having an @Configurable
    on the EmailConstraintValidator class and trying to auto-wire the bean which i want to inject but am getting :

    “BeanFactory has not been set on BeanConfigurerSupport: Make sure this configurer runs in a Spring container. Unable to configure bean of type [com.my.package.EmailConstraintValidator ]. Proceeding without injection.”

    Any idea or thoughts how to best be able to inject a bean inside of a custom hibernate validator constraint?

  9. September 24, 2009 at 03:52 by John Vance

    So, what about Javascript integration? How about with Spring Javascript?

  10. […] the classpath and using maven this is as simple as adding the following in your pom.xml.   This  post has lot more information on the JSR 303 […]

  11. October 24, 2009 at 03:00 by Aswin

    Spring 3.0 adds support for @Valid annotation, so a lot of this becomes easier. But this was a very good writeup and I really enjoyed it. The @Valid annotation is pretty easy to configure (http://omgo.wordpress.com/2009/10/24/spring-mvc-3-x-valid-jsr-303-annotation-support/) as most of it is already covered in your post. Thanks again for this wonderful post.

  12. December 18, 2009 at 07:26 by Alex

    Add the check below to prevent JSR-303 valiation if the Spring DataBinder already registered an error on the path: if (!errors.hasFieldErrors(propertyPath)) { errors.rejectValue(propertyPath, “”, message); }

    That way a failed binding (e.g. “Date is invalid!”) won’t include failed JSR-303 validation (e.g. “Date is required”).

  13. January 20, 2010 at 21:17 by Thomas

    Spring modules validation had the applyIf construct that allowed you to do conditional or dependent validations. JSR-303 seems to be silent on this aspect. Any thoughts?

  14. February 2, 2010 at 15:53 by Ferenc

    I agree with Thomas that the applyIf construct is missing from JSR-303. It made the conditional validation much easier. Like:

    import org.springmodules.validation.bean.conf.loader.annotation.handler.Range;

    public class Product {
    @Range(min=1, max=999)
    private Long category;

    @Range(min=1, max=999, applyIf="category > 0")
    private Long subCategory; // Check only if the category is selected
    }

    I also miss the @Range (checks that a java.lang.Comparable value is within a specific range) and the @NotBlank (checks that a string value is not blank, holds some characters) validations, but they can be replaced by @Min + @Max or some regexp.

  15. February 8, 2010 at 21:52 by praveen

    I am getting following error when I am trying to run tomcat server
    Invocation of init method failed; nested exception is org.hibernate.HibernateException: Unable to get the default Bean Validation factory. Kindly assist me

  16. March 1, 2010 at 11:51 by Ross

    @Christoph

    Please could you post your solution — I have a similar setup as you and I am looking for the same functionality. I have tried a number of things but at the moment just not working.

    thanks

  17. March 1, 2010 at 20:37 by Michael Chang

    Hey, Uri. Thanks so much for the thorough writeup. There’s not too much out there yet for Google to pick up, so any pointers on this new spec are helpful.

    Anyway, I tried creating a little test to test this whole thing out using Spring MVC (3.0) and Hibernate Validation (4.0.2). I created a simple form that captures a ‘name’ and an ‘ID’, which were backed by a form bean containing a String and a Long, respectively. I wired up a Spring controller using annotations (specifically, @Valid). The form displays correctly, and I intentionally enter data that violates the constraints. Now here’s where the problem comes in. When I submit the form, I get a 500 error and a long stacktrace with the following message: “javax.validation.UnexpectedTypeException: No validator could be found for type: java.lang.Long”. I tried replacing the wrapper Long with a primitive ‘long’ type, but the same exception gets thrown with the same error message. So my understanding now is that the new Bean Validation is not even able to understand primitive types except for ‘String’. That’s almost as bad as javac not understanding a ‘char’ or ‘byte’. If I turn on debug logging, I see that Spring itself is able to convert from the submitted form’s String to a Long. It’s the validator itself that doesn’t understand what a Long is (the validator fires after Spring has finished performing conversion, according to the call sequence indicated in the logs). Uri, can you confirm that this is true? Try doing this yourself by using a command/form-bean containing a Long (you don’t even need to put a constraint on it, in fact), and see if you can submit a form. I find it hard (or even impossible) to believe that it can’t understand even primitive types, so I’m assuming that there is some kind of disagreement between Spring and Hibernate Validator.
    I’d appreciate it if you could test this out and see if you can duplicate this. If so, a bug report is in order.

    Michael Chang

  18. March 28, 2010 at 04:01 by Andrew Swan

    > The only thing that is left to do, is to create a ValidationMessage.properties file

    That should say “ValidationMessages.properties”, with an “s” before the dot.

  19. April 15, 2010 at 22:10 by Alex

    Hey. Does anybody realized how to live without applyIf? Can it be emulated using another construct?

  20. May 5, 2010 at 02:11 by Mimi Tam

    I am getting the following exception and have same thought as Michael Chang.

    “No validator could be found for type: java.lang.Long”

    Is there any other info on this? Is there any workaround?

    How was this resolved?

    Thanks.

  21. May 13, 2010 at 13:13 by Daniel

    i am getting the same exception as well, but for Integer types

    No validator could be found for type: java.lang.Integer

    I did nothing more than @Min(value = 5, message=”my message”)

    It works nice just for @NotEmpty values!

    What is worng?

  22. May 14, 2010 at 08:42 by sandy

    Is there any way to specify our own ResourceBundle? I would like to use, say, TestValidationMessages.properties apart from ValidaitonMessages.properties?

  23. May 15, 2010 at 23:46 by Erik

    Great post. Thanks.

    @sandy:
    Check out this post: http://java.dzone.com/articles/using-hibernate-validator , under “Customizing Error Messages”.

  24. […] Bean Validation: Integrating JSR-303 with Spring […]

  25. […] http://blog.jteam.nl/2009/08/04/bean-validation-integrating-jsr-303-with-spring/ (Un post molto valido e completo, pieno di esempi anche a livello avanzato) […]

  26. March 22, 2011 at 02:02 by thetoolman

    Hey Uri,

    Thanks for the writeup. As others have noted, there seems to be no “applyIf” construct, so I’m thinking that any time you need conditionals, you will need to write a validator, right ?

  27. July 10, 2011 at 21:14 by Dumitru Postoronca

    Please note that ConstraintPayload has been renamed to Payload.

  28. March 9, 2012 at 17:39 by stanilas@yahoo.fr

    its @pattern not @Mask ^^

  29. June 5, 2012 at 14:05 by Petru Guzun

    Hello,
    I followed this good exemple but get into another problem. Can you please help me?
    I am using REST design so all i reused is your custom Loading constraint validators from spring.

    It get Exception when ConstraintValidator#initialize(T annotationConstraint) is called with Caused by: java.lang.ClassCastException: $Proxy84 cannot be cast to Clazz
    here is the problem i have described
    http://stackoverflow.com/questions/10880061/how-to-solve-cast-issue-java-lang-classcastexception-proxy-cannot-be-cast-to-n

    Thanks a lot for your time,
    with respect Petru.

  30. June 25, 2013 at 17:06 by john

    Hi,
    Is it possible to use the validator in a normal spring @service and not in an MVC component?
    How can I pass the Errors errors variable??

    thanks

  31. November 22, 2013 at 15:59 by Thanh Son

    I am a java & Spring developer .That’s a helpful post

  32. January 15, 2014 at 13:46 by Rama

    Hi All,

    I want to set a custom error message via @Controller, there is something like Struts saveMessages(…) in Spring MVC Framework ? for example:

    ActionErrors actionErrors = new ActionErrors();
    actionErrors.add(“error”, new ActionMessage(“error.missing.key”,
    messageResources.getMessage(“label.username”),
    messageResources.getMessage(“label.password”)));
    saveErrors(request, …)

    Any suggestion would be appreciated.

    Regards,
    Rama

  33. May 22, 2015 at 20:48 by Alabama Mothman

    I for one cant believe that coders believe putting these ranges and constraints in the source code is a good idea. Why cant these be added in the servlet.xml

    I personally have been programming for over 25 years and this type of coding was a sign of amateurism could get you fired.

    Come on guys, we can do better than this.