Отловить исключение при сохранении сущности, CrudRepository Spring

Пытаюсь отловить исключение при попытке дублирования полей во время сохранения пользователя (на поле ограничение UNIQUE). Использую save от CrudRepository, в документации следующее описание метода:

Returns: the saved entity; will never be null.
Throws: IllegalArgumentException - in case the given entity is null.

Но что если ошибка будет при выполнении запроса?

Контроллер:

@PostMapping(value = "/api/users/save")
public ResponseEntity save(@Valid @RequestBody User user) {
    User newUser = userService.save(user);
    log.info(newUser);
    return ResponseEntity.ok(newUser);
}

Сервис:

@Override
public User save(User user) {
    user.setId(userRepository.getLastId());
    user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
    User newUser = null;
    try {
        newUser = userRepository.save(user); // никаких исключений
    } catch (Exception e) {
        log.error("CATCH STATEMENTS");
    } finally {
        log.info("FINALLY STATEMENTS");
    }
    return newUser;
}

Но при попытке сохранить пользователя я получаю ошибку:

ERROR 16228 --- [nio-8080-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper   : ORA-00001: нарушено ограничение уникальности (STORM.USERS_EMAIL_UINDEX) 
java.sql.SQLIntegrityConstraintViolationException: ORA-00001: нарушено ограничение уникальности (STORM.USERS_EMAIL_UINDEX)

Сервис возвращает мне пользователя при выполнении save, а при передаче запроса (?) выбрасывает ошибку. Где отловить исключение я уже отчаялась найти.

Кстати, еще я пробовала проверять статус ответа в фильтре, но до фильтра выполнение просто не доходит. Возможно у вас есть идеи, где бы я смогла отловить исключение, спасибо.

#UPDATED

При попытке отловить RuntimeException или DataIntegrityViolationException суть не меняется (

log.warn("Try to save user");
try {
    return userRepository.save(user);
} catch (RuntimeException e) {
    log.error("Failed to save user");
}

И вот результат: введите сюда описание изображения


Ответы (2 шт):

Автор решения: DmitryD

На сколько помню userRepository.save(user); выбросит исключение, наследуемое от RuntimeException, вам нужно это дело обернуть в блок try-catch и обработать исключение по своему.

try {
   ...
} catch(RuntimeException e) {
   log.error("SQL error", e);
}

Создал локально минимально воспроизводимый пример и получилось таким образом отловить ошибку.

введите сюда описание изображения

→ Ссылка
Автор решения: Warheart

Вы не можете отловить, потому что там RuntimeException нужно ловить, а если конкретней, то DataIntegrityViolationException. Почитать можно например тут

→ Ссылка