Search code examples
hibernatevalidationspring-mvcbean-validationhibernate-validator

Hibernate bean validation issue


I am using spring 3.1 with hibernate validator 4.2. I observe that hibernate validation gets invoked two times: One at controller level when i use method like:

 @RequestMapping(method = RequestMethod.POST)
    public String onSubmit(@Valid User user, BindingResult result) {....}

And 2nd time when entities are persisted as part of:

org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(..)
org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreUpdate(..)
org.hibernate.action.EntityUpdateAction.preUpdate(..)

I believe it makes more sense to valid at controller level and display error page with error messages. And anyway, doing same validation two times in flow not good. I found in hibernate doc that it can be turned off by setting hibernate.validator.autoregister_listeners to false in hibernate configuration but it is not recommended.

So what is recommended approach for validation? Also in my particular case 2nd validation causes trouble because I have a field 'confirmPassword' which is required for validation when user submits form but is not required in table so whenever i have to save, update user, I have to set confirmPassword field unnecessarily just to make validation pass.


Solution

  • Validation isn't an easy thing in spite of appearances.

    The frontend validation is for the user that fills the form,and could change from a view to another view (different messages for example). The message for a required field in the view should be "The field is mandatory !", in the backend when the entity is persisted : "field cannot be null".

    The backend validation should occur ALWAYS when a class is saved, consider infact that a persistent entity could be saved without passing from the view (for example from a batch that receive data from a webservice or from queues ora another source..).

    If you put a validation annotation at entity level you enforce a contract on that class that is independent from the fact that the class has been used in a view or not.

    ConfirmPassword is a view field, so i think should not be present as field in the entity (for example, I developed a similar case with JSF, i put confirmPassword in the ManagedBean related to that view and not in the entity, the entity contain only the password field).

    Summarizing therefore i think is correct doing the 'same' validation twice.