【问题标题】:Reproducing SQL Exception and correct handling in layer architecture在层架构中重现 SQL 异常和正确处理
【发布时间】:2020-03-23 16:04:24
【问题描述】:

假设我有这个:

String sql = "DELETE FROM "+ TABLE_NAME +"  WHERE id=?";
       
try {
    int ra = jdbcTemplate.update(connection -> {
                PreparedStatement stmt = connection.prepareStatement(sql);
                stmt.setLong(1, id);
                stmt.executeUpdate();
                return stmt;
            });

    if (ra == 0)
        throw new SQLException(SQL_ERROR);
} catch (SQLException e){
    LOGGER.error(SQL_ERROR);
    throw new DataAccessLayerException("Entity could not be deleted due to SQL Exception");
}

我正在使用 key(id) 从表中删除一个实体。现在我希望能够向客户报告INTERNAL_SERVER_ERROR 而不会导致RuntimeException

但是,我无法重现 SQLException。例如,如果我在我的 sql 语句中删除一个字母,我只会得到一个作为运行时错误抛出的语法错误,而且似乎我没有抓住它。

帮助我了解 SQLException 的确切含义以及如何重现它并将其报告给客户端而不导致 RuntimeException?

【问题讨论】:

    标签: java sql spring-boot jdbc jdbctemplate


    【解决方案1】:

    您的代码错误。您正在调用update(PreparedStatementCreator psc),顾名思义,您的代码应该创建一个完全“准备好的”语句对象,但它不应该“执行”该语句,因此删除executeUpdate() 调用。

    update() 调用会抛出 DataAccessException,而不是 SQLException,因此 SQLExceptiontry 块中的唯一来源是您的 if 语句,所以您不妨直接抛出 @ 987654332@ 直接异常。不过,我建议改为使用EmptyResultDataAccessException

    由于 Spring 专门将已检查的 SQLException 转换为未检查的 DataAccessException 运行时异常,因此在使用 Spring JDBC 时总是会遇到运行时异常,这是一个好事,因为你现在不会'不需要为代码中的所有方法添加检查异常。

    Spring MVC 处理未处理的异常。默认情况下,Spring MVC 将重定向到错误页面。如果你不想这样,请参阅例如问题Spring Boot Remove Whitelabel Error Page

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-24
      • 2011-04-05
      相关资源
      最近更新 更多