In the version of Springboot 3.2.1, following worked:

  • class with jakarta.validation.constraints.Size annotation on a field
  • Java controller request body with given class annotated with jakarta.validation.Valid;
  • Class anotated with ControllerAdvice and @ExceptionHandler(MethodArgumentNotValidException.class) was handling validation exceptions

After spring-boot-starter upgrade to 3.2.2 (and also 3.2.3), MethodArgumentNotValidException is not raised anymore, HandlerMethodValidationException is raised instead.

Comment From: wilkinsona

There were some notable changes in this area in Spring Framework 6.1 (https://github.com/spring-projects/spring-framework/issues/29825). The change that you're seeing may be as a result of a refinement of those changes in a Spring Framework patch release. It's hard to be certain with the level of detail that you've currently provided. You could try using spring.version to override the version of Spring Framework that's used to see if this changes the behavior. If it does, then this will have to be investigated by the Spring Framework team. If it does not then we'll need some more information in the form of a minimal sample that we can use to reproduce the behavior you have described.

Comment From: scottfrederick

This comment on a Spring Framework issue might also be relevant.

Comment From: pepavesely

Hi, @scottfrederick thank you for the link. This issue seems to be duplicate of that one.

@PostMapping("/test1")
ResponseEntity<String> test1(@Valid @RequestBody TestModel testModel) {
    return ResponseEntity.ok().build();
}

throws MethodArgumentNotValidException but

@PostMapping("/test2/{param}")
ResponseEntity<String> test2(
        @NotNull @PathVariable(name = "param") String param,
        @Valid @RequestBody TestModel testModel) {
    return ResponseEntity.ok().build();
}

throws HandlerMethodValidationException

My pom.xml is fairly simple:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.2.4</version>
    <relativePath/>
</parent>

<properties>
    <java.version>17</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>
   <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

TestApplication.class:

package com.example.test;

import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Data;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.method.annotation.HandlerMethodValidationException;

@ControllerAdvice
@RestController
@SpringBootApplication
public class TestApplication {

    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class, args);
    }

    @PostMapping("/test1")
    ResponseEntity<String> test1(@Valid @RequestBody TestModel testModel) {
        return ResponseEntity.ok().build();
    }

    @PostMapping("/test2/{param}")
    ResponseEntity<String> test2(
            @NotNull @PathVariable(name = "param") String param,
            @Valid @RequestBody TestModel testModel) {
        return ResponseEntity.ok().build();
    }

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<String> handleException(final MethodArgumentNotValidException ex) {
        return ResponseEntity.badRequest().build();
    }

    @ExceptionHandler
    public ResponseEntity<String> handleUncaughtExceptions(final HandlerMethodValidationException ex) {
        return ResponseEntity.badRequest().build();
    }

    @Data
    public static class TestModel {

        @Size(min = 3)
        private String name;
    }
}

In spring-boot-starter-parent version 3.2.1, both cases are handled by MethodArgumentNotValidException

Comment From: wilkinsona

Thanks, @pepavesely. Closing as a duplicate of https://github.com/spring-projects/spring-framework/issues/32396.