【问题标题】:Spring: Inconsistent precedence of exception handling vs try catch blockSpring:异常处理与尝试捕获块的优先级不一致
【发布时间】:2021-10-11 13:44:42
【问题描述】:

有一个 spring boot/jpa 应用程序。 在下面的代码中 - 如果 createEntity() 方法中的保存调用引发 DataIntegrityViolationException,则 异常在 EntityExceptionHandler 中被捕获 - 而不是在(try-catch 的)块中。 如果从 createEntity 方法(服务类)中删除了 @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("");
    }
}

【问题讨论】:

    标签: spring spring-boot spring-mvc spring-data-jpa


    【解决方案1】:

    事务一提交到数据库就会发生异常。 如果该方法使用@Transactional 注释,则提交发生在“包装器”中,而不是在 createEntity 方法本身中。因此 try-catch 块没有任何作用。

    带有@Transactional 的伪代码:

    beginTransaction()
    try {
      entityRepository.save(...)
    } catch (....) {}
    endTransaction() <- here the exception is thrown
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-14
      • 2018-02-06
      • 2015-04-14
      • 2014-04-10
      • 2020-07-31
      • 1970-01-01
      • 1970-01-01
      • 2020-08-14
      相关资源
      最近更新 更多