Poliakoff
Poliakoff

Reputation: 1672

Couldn't catch DataIntegrityViolationException with Spring Data REST

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);
}

Upvotes: 1

Views: 3605

Answers (1)

Slava Gornostal
Slava Gornostal

Reputation: 419

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.

Upvotes: 1

Related Questions