i am continuing my journey to learn Spring boot, right now i am stuck between two similar kind of exceptions, wherever i found i have got the answer that if @valid or @validate used at controller/service level along with @RequestBody we should get MethodArgumentNotValidException whereas, i am getting ConstraintViolationException during post and update API calls. again and again the call is going in globalExceptionHandler method of ExceptionHAndler class, where it is showing constraintviolationexception.
PostController.java
@RestController
@RequestMapping("/api/posts")
public class PostController {
@Autowired
private PostService postService;
//rest API endpoint to post http:localhost:8080/api/posts
@PostMapping
public ResponseEntity<PostDTO> createPost(@Valid @RequestBody PostDTO postDTO){
return new ResponseEntity<>(postService.createPost(postDTO),HttpStatus.CREATED);
}
@PostMapping(path = "/multiple")
public ResponseEntity<List<PostDTO>> createMultiplePosts(@Valid @RequestBody List<PostDTO> postDTO){
return new ResponseEntity<>(postService.createMultiplePosts(postDTO),HttpStatus.CREATED);
}
Entity Class:
Posts.java
@Entity
@Table(name = "posts", uniqueConstraints = {@UniqueConstraint(columnNames = {"titles"})})
public class Posts {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
@Column(name = "titles")
@NotEmpty
@Size(min = 2,message = "post title should contain atleast 2 character")
private String title;
@Column(name = "description")
@NotEmpty
@Size(min = 10,message = "post description should contain atleast 2 character")
private String description;
@Column(name = "content")
@NotEmpty
private String content;
GlobalException.java
@ControllerAdvice
public class GlobalException extends ResponseEntityExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(GlobalException.class);
@ExceptionHandler(ResouceNotFoundException.class)
ResponseEntity<ErrorDetails> PostNotFoundExceptionHandler(ResouceNotFoundException exception, WebRequest webRequest){
ErrorDetails errorDetails =new ErrorDetails(new Date(),exception.getMessage(),webRequest.getDescription(false));
return new ResponseEntity<>(errorDetails,HttpStatus.NOT_FOUND);
}
@ExceptionHandler(BlogApiException.class)
ResponseEntity<ErrorDetails> CommentNotFoundExceptionHandler(BlogApiException exception, WebRequest webRequest){
ErrorDetails errorDetails =new ErrorDetails(new Date(),exception.getMessage(),webRequest.getDescription(false));
return new ResponseEntity<>(errorDetails,HttpStatus.NOT_FOUND);
}
@Override
// @ExceptionHandler(MethodArgumentNotValidException.class)
protected ResponseEntity<Object> handleMethodArgumentNotValid(
MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request){
logger.info("inside handleMethodArgumentNotValid class");
Map<String, String> errorsMap =new HashMap<>();
ex.getBindingResult().getAllErrors().forEach((error)->{
String fieldNameString = ((FieldError)error).getField();
String messageString = error.getDefaultMessage();
errorsMap.put(fieldNameString, messageString);
});
return new ResponseEntity<>(errorsMap,HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(Exception.class)
ResponseEntity<ErrorDetails> GlobalExceptionHandler(Exception exception, WebRequest webRequest){
logger.info("inside GlobalExceptionHandler class");
ErrorDetails errorDetails =new ErrorDetails(new Date(),exception.getMessage(),webRequest.getDescription(false));
return new ResponseEntity<>(errorDetails,HttpStatus.BAD_REQUEST);
}
}
i tried modifying RequestBody JSON, tried @validated annotation at class level, and at method level after @RequestBody annotation as well, still getting same exception. please help me to understand why am I getting this exception, tried playing with versions of spring boot starter validation dependency. currently using 3.0.4 version of starter-validation dependency Java version is 17.0.7
Why do you think you should get MethodArgumentNotValidException
? ConstraintViolationException
seems to be totally reasonable exception to expect, when some constraints were violated by your request body. I don't see a problem here. Just change your ExceptionHandler
to catch ConstraintViolationException
and do whatever you want with it.