У меня есть веб-приложение REST.
При выполнении запроса PUT на ресурс под названием ThingGroup
мой контроллер вызывает слой службы, как этотНевозможно уловить исключения в служебном слое
@RequestMapping(method = RequestMethod.PUT)
@ResponseBody
public void updateThingGroup(@Valid @RequestBody final ThingGroup thingGroup, final Principal principal) throws UnknownResourceException {
final User user = userService.findByUserName(principal.getName());
thingGroupService.update(thingGroup, user);
}
И соответствующий thingGroupService
, который @Transactional
@Override
@Transactional
public ThingGroup update(final ThingGroup thingGroup, User user){
ThingGroup found = null;
try {
found = find(thingGroup.getId(),user);
found.setName(thingGroup.getName());
found = getDao().save(found);
} catch (final DataIntegrityViolationException e) {
// I want to throw that custom exception here
MyBadRequestException ex = new MyBadRequestException("MyBadRequestException.update.violation.thingGroup", "violation_data_integrity");
ex.setParameters(new Object[] { thingGroup.getName()});
throw ex;
}
return found;
}
В основной базе данных MySQL У меня есть ограничение единства на имени thingGroup.
Так что если я попытаюсь обновить вещьGroup с существующим именем, она не сработает.
Когда он терпит неудачу, я хотел бы бросить специальное исключение, чтобы передать понятное сообщение на уровень контроллера.
Моя проблема заключается в том, что из-за аннотации @Transactional
исключения Hibernate выдаются после совершения транзакции, что означает, что после возврата метода обслуживания (я думаю).
А это означает, что я не могу поймать исключение на сервисном уровне.
У меня есть ответы на подобные ответы, и, как я понял, мне нужно будет поймать исключение на уровне контроллера. Однако это не кажется хорошим решением, потому что уровень контроллера должен быть осведомлен о базовом поведении уровня сервиса, что не очень хорошо.
Есть ли общее решение этой проблемы?
Будут ли автоматические откаты работать должным образом, если я подключу несколько методов @Transactionnal, используя saveAndFlush, и один из них не работает? – singe3
Несомненно, флеш просто синхронизирует текущие изменения (выполняет DML) в базе данных, он не фиксирует транзакцию. –
Хорошо, я попробую. – singe3