Spring:异常处理与 try catch 块的优先级不一致
Spring: Inconsistent precedence of exception handling vs try catch block
有 spring boot/jpa 申请。
在下面的代码中 - 如果 createEntity() 方法中的保存调用引发 DataIntegrityViolationException,则
异常在 EntityExceptionHandler 中被捕获 - 而不是在 catch(try-catch 的)块中。
如果从 createEntity 方法(服务 class)中删除 @Transactional 注释,则
DataIntegrityViolationException 是在 catch 块中捕获的,而不是在异常处理程序中。
这可以解释一下吗?我不明白其中的矛盾。
此外,如果在 EntityController 中的 createEntity 调用周围放置一个 try-catch 块,则异常
在 catch 块中被捕获 - 而不是在异常处理程序中 - 无论 @Transactional 是否
注释已设置。这也能解释一下吗?
谢谢。
public class EntityController {
@PostMapping(value = "/entities")
@ResponseBody
public ResponseEntity postEntity(@RequestBody entity) {
entityService.createEntity(entity);
return ResponseEntity.status(HttpStatus.CREATED)...;
}
}
@Repository("EntityRepository")
public interface EntityRepository extends JpaRepository<Entity, UUID> {}
@Service
public class EntityServiceImpl implements EntityService {
@Autowired
private EntityRepository entityRepository;
@Override
@Transactional
public void createEntity() {
Entity entity = new Entity(...);
try {
entityRepository.save(entity);
} catch (DataIntegrityViolationException ex) {...}
}
}
@ControllerAdvice
public class EntityExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(DataIntegrityViolationException.class)
@ResponseBody
public ResponseEntity<Object> handleDataIntegrityViolationException(DataIntegrityViolationException ex, WebRequest request) {
return ResponseEntity.status(HttpStatus.CONFLICT).headers(new HttpHeaders()).body("");
}
}
事务一提交到数据库就出现异常。
如果该方法用@Transactional 注释,则提交发生在“包装器”中,而不是在 createEntity 方法本身中。因此 try-catch 块无效。
带有@Transactional 的伪代码:
beginTransaction()
try {
entityRepository.save(...)
} catch (....) {}
endTransaction() <- here the exception is thrown
有 spring boot/jpa 申请。 在下面的代码中 - 如果 createEntity() 方法中的保存调用引发 DataIntegrityViolationException,则 异常在 EntityExceptionHandler 中被捕获 - 而不是在 catch(try-catch 的)块中。 如果从 createEntity 方法(服务 class)中删除 @Transactional 注释,则 DataIntegrityViolationException 是在 catch 块中捕获的,而不是在异常处理程序中。
这可以解释一下吗?我不明白其中的矛盾。
此外,如果在 EntityController 中的 createEntity 调用周围放置一个 try-catch 块,则异常 在 catch 块中被捕获 - 而不是在异常处理程序中 - 无论 @Transactional 是否 注释已设置。这也能解释一下吗?
谢谢。
public class EntityController {
@PostMapping(value = "/entities")
@ResponseBody
public ResponseEntity postEntity(@RequestBody entity) {
entityService.createEntity(entity);
return ResponseEntity.status(HttpStatus.CREATED)...;
}
}
@Repository("EntityRepository")
public interface EntityRepository extends JpaRepository<Entity, UUID> {}
@Service
public class EntityServiceImpl implements EntityService {
@Autowired
private EntityRepository entityRepository;
@Override
@Transactional
public void createEntity() {
Entity entity = new Entity(...);
try {
entityRepository.save(entity);
} catch (DataIntegrityViolationException ex) {...}
}
}
@ControllerAdvice
public class EntityExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(DataIntegrityViolationException.class)
@ResponseBody
public ResponseEntity<Object> handleDataIntegrityViolationException(DataIntegrityViolationException ex, WebRequest request) {
return ResponseEntity.status(HttpStatus.CONFLICT).headers(new HttpHeaders()).body("");
}
}
事务一提交到数据库就出现异常。 如果该方法用@Transactional 注释,则提交发生在“包装器”中,而不是在 createEntity 方法本身中。因此 try-catch 块无效。
带有@Transactional 的伪代码:
beginTransaction()
try {
entityRepository.save(...)
} catch (....) {}
endTransaction() <- here the exception is thrown