1
votes

Trying to handle DataIntegrityViolationException with ControllerAdvice and return a custom response with Spring Boot v 1.3.3 & Spring Data REST v 2.4.4. Here are my classes:

ExceptionControllerAdvice.java

@ResponseStatus(HttpStatus.CONFLICT)
@ExceptionHandler(DataIntegrityViolationException.class)
public ViolationResponse handleConflictException(DataIntegrityViolationException ex) throws Exception {
    return new ViolationResponse(ex.getMessage());
}

ViolationResponse.java

public class ViolationResponse {

private String message;

public ViolationResponse(String message) {
    this.message = message;
}

public String getMessage() {
    return message;
}

public void setMessage(String message) {
    this.message = message;
}
}

I expect this to return 409 Conflict HTTP status code with message

{"message" : "..."}

But I got 404 status with this response instead:

{ "timestamp": 1463382639043 "status": 404 "error": "Not Found" "exception": "org.springframework.dao.DataIntegrityViolationException" "message": "could not execute statement; SQL [n/a]; constraint [email_exists_constraint]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement" "path": "/api/v1/register" }

What am I missing here? How to achieve the desired result?

EDIT:

AuthController.java

@RestController
@RequestMapping("/api/v1")
public class AuthController {
...
@RequestMapping(value = "/register", method = RequestMethod.POST)
public User register(@Valid @RequestBody User user, BindingResult result) throws ValidationException {
    if (result.hasErrors()) {
        throw new ValidationException(result.getAllErrors());
    }
    return userRepository.save(user);
}
1
Show us the class declaration of Controller and the method signature responsible for handling /api/v1/register please. - miensol
Hmmm, is the ExceptionControllerAdvice marked with @ControllerAdvice and created on application startup? - miensol
@miensol Yes, ExceptionControllerAdvice is annotated with @ControllerAdvice and is working as expected with another method I use there. The application even executes code inside handleConflictException method what can be seen during debugging. But instead of expected response, I get Spring Boot default response. - Poliakoff
check out the accepted answer at this post stackoverflow.com/questions/32052092/… - Abdullah Khan

1 Answers

1
votes

Annotate your method handleConflictException in ExceptionControllerAdvice.java with @ResponseBody. This will tell spring to make a JSON from your return object. @RestController has @ResponseBody inside, @ControllerAdvice do not.