When I started to use Spring Boot I had some issues with the validation. The @Validated annotation triggered the validation as requested but the validation terminated with an org.springframework.validation.BindException instead of filling the BindingResult object.

My initial method looked similar to this one:

@PostMapping("/do-something")
@PreAuthorize("hasRole('ADMIN')")
public String update(Model model,
   @ModelAttribute @Validated RequestDAO requestData,
   @CurrentUser User user,
   BindingResult bindingResult) {
   [...]
}

To resolve this issue I used the debugger to see what happens inside...
 

/* org.springframework.web.method.annotation.ModelAttributeMethodProcessor#resolveArgument */
validateIfApplicable(binder, parameter);
if (binder.getBindingResult().hasErrors() && isBindExceptionRequired(binder, parameter)) {
    throw new BindException(binder.getBindingResult());
}

/* org.springframework.web.method.annotation.ModelAttributeMethodProcessor#isBindExceptionRequired */
/**
 * Whether to raise a fatal bind exception on validation errors.
 * @param parameter the method parameter declaration
 * @return {@code true} if the next method parameter is not of type {@link Errors}
 * @since 5.0
 */
protected boolean isBindExceptionRequired(MethodParameter parameter) {
	int i = parameter.getParameterIndex();
	Class<?>[] paramTypes = parameter.getExecutable().getParameterTypes();
	boolean hasBindingResult = (paramTypes.length > (i + 1) && Errors.class.isAssignableFrom(paramTypes[i + 1]));
	return !hasBindingResult;
}

Therefore the correct order of the method arguments is very important. The BindingResult has to follow the @Validated attribute, otherwise an org.springframework.validation.BindException is thrown.

So the working code looks like this:

@PostMapping("/do-something")
@PreAuthorize("hasRole('ADMIN')")
public String update(Model model,
   @ModelAttribute @Validated RequestDAO requestData,
   BindingResult bindingResult, /* BindingResult must follow @Validated */
   @CurrentUser User user) {
   [...]
}