11

I'm using spring 4.1, hibernate validator 5.1.3 for my project. I've been trying to get the GroupSequence to work from last 2 days. I've referred the validation doc, blogs and a few questions posted on stackoverflow.

Please see the below class. When I remove the GroupSequence and groups from the annotations, all the validation messages come up together, i.e, all the checks on name and other fields are fired together. Lets say for name field - I want @NotBlank and @Size to be validated first, then the name should be matched with the Pattern and at last it should be checked for @UniqueName because of the database calls.

For that, I created the GroupSequence, as suggested in the docs and answers. But when the validations are fired, only @NotBlank and @Size are fired for name. When I remove the groups value from the remaining annotations, they start working but all the error messages are shown at once, which I don't want.

I want the annotation specified with groups First.class are fired together and before Second.class validations. I don't get why the validations specified with groups aren't getting fired.

Can someone please guide me.


@GroupSequence({MyForm.class, OrderedChecks.class})
public class MyForm {

  @NotBlank
  @Size(min = 2, max = 40)
  @Pattern(regexp = "^[\\p{Alnum} ]+$", groups = First.class)
  @UniqueName(groups = Second.class)//Custom validation
  private String name;

  @NotBlank
  @Size(min = 2, max = 40)
  private String url;

  @NotBlank
  @Size(max = 100)
  private String imagePath;

  //Custom Validation
  @CheckContent(acceptedType = <someString>, allowedSize=<someval>, dimensions=<someval> groups = Second.class)
  private MultipartFile image

...
}

@GroupSequence(value = {Default.class, First.class, Second.class})
public interface OrderedChecks {}

@Controller
@RequestMapping(value = "/myForm")
public class MyFormController {

    @RequestMapping(method = POST)
    public String completeSignUp(@Valid @ModelAttribute("myForm") final MyForm myForm,
                            BindingResult result, RedirectAttributes redirectAttributes, Model model) {

        if(result.hasErrors()) {
            model.addAttribute(companyDetailsForm);
            //ERROR_VIEW="myForm";
            return ERROR_VIEW;
        }
       // Doing something else.
      return <success view>;
   }
}
jay
  • 171
  • 4
  • 13
  • Does anyone has any idea about the resolution or what I might be doing wrong? – jay Dec 29 '14 at 07:27
  • Can you update the question with the code where the validation is not working as expected (e.g. the controller method)? – Khalid Dec 29 '14 at 09:41
  • @Khalid added the controller code, it is working but not as I expect it to. I'll have to use a hack to get it working, which I have in my mind but I'm looking for something available in spring mvc rather than putting in my hack. I'll have to put those checks in my custom annotation, but even in that case I don't know if I can change the error message for a field, like name which has four annotations, based on the failed condition. I've defined the error messages in a property file. – jay Dec 29 '14 at 16:22

1 Answers1

12

Use Spring's @Validated instead of @Valid. This will allow you specify the group and control the sequence.

Change your controller method to:

@RequestMapping(method = POST)
public String completeSignUp(@Validated(OrderedChecks.class) @ModelAttribute("myForm") final MyForm myForm,
                        BindingResult result, RedirectAttributes redirectAttributes, Model model) {
...
}

Note that you don't need @GroupSequence({MyForm.class, OrderedChecks.class}) on top of MyForm bean.

Khalid
  • 2,212
  • 11
  • 12
  • I tried it, but didn't work last time. I'll give it a try again. – jay Dec 29 '14 at 17:00
  • as suggested, I made the changes and its not working. Validations belonging to a group are not fired. – jay Dec 29 '14 at 17:25
  • It's working for me. Make sure the value can actually trigger the `@Pattern` and `@UniqueName` constraints. If you're sure, turn on Spring's debug logging and look for any hints. – Khalid Dec 29 '14 at 17:37
  • I used the values which would trigger `@Pattern` and `@UniqueName`, but they are not fired even then. I enabled debug logging and couldn't see anything in that. I did this in log4j.properties - **org.springframework=DEBUG**. Is there a way to enable logging for spring mvc only or for bean validation? – jay Dec 30 '14 at 16:32
  • can you please share your code along with the configuration. Have you added a validator bean in the servlet context file? – jay Dec 31 '14 at 07:34
  • I debugged the validator and the validations with groups - First or Second assigned are not executed. Do you know why is this happening? If I remove the groups then all the validations are fired. – jay Jan 04 '15 at 07:08
  • Not really sure. Perhaps you should update the question with the debug log, in addition to the updated code using `@Validated`. – Khalid Jan 04 '15 at 07:42
  • Thanks for the response, it is working now. Cheers!!! My bad, I was ignoring a default group validation failure and was monotonously thinking about the custom validators not working. Was thinking too much in that direction only. – jay Jan 04 '15 at 10:06