重现 SQL 层架构中的异常和正确处理
Reproducing SQL Exception and correct handling in layer architecture
假设我有这个:
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");
}
我正在使用密钥 (id) 从 table 中删除一个实体。现在我希望能够向客户报告 INTERNAL_SERVER_ERROR
而不会导致 RuntimeException
.
但是,我无法重现SQLException
。例如,如果我在我的 sql 语句中删除一个字母,我只会收到一个作为运行时错误抛出的语法错误,而且我似乎没有捕捉到它。
帮助我理解这里 SQLException 的确切含义,以及如何在不导致 RuntimeException 的情况下重现它并将其报告给客户端?
您的代码有误。您正在呼叫 update(PreparedStatementCreator psc)
, and as the name suggests, your code should create a fully "prepared" statement object, but it should not "execute" that statement, so remove the executeUpdate()
呼叫。
update()
调用抛出 DataAccessException
,而不是 SQLException
,因此 try
块中 SQLException
的唯一来源是您的 if
语句,所以你最好直接抛出 DataAccessLayerException
异常。不过,我建议改用 EmptyResultDataAccessException
。
由于Spring专门将已检查的SQLException
转换为未检查的DataAccessException
运行时异常,所以使用SpringJDBC时总是会出现运行时异常,并且这是一件好事,因为您现在不需要向代码中的所有方法添加已检查的异常。
未处理的异常由 Spring MVC 处理。默认情况下,Spring MVC 将重定向到错误页面。如果你不想要那个,请参见例如问题 Spring Boot Remove Whitelabel Error Page.
假设我有这个:
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");
}
我正在使用密钥 (id) 从 table 中删除一个实体。现在我希望能够向客户报告 INTERNAL_SERVER_ERROR
而不会导致 RuntimeException
.
但是,我无法重现SQLException
。例如,如果我在我的 sql 语句中删除一个字母,我只会收到一个作为运行时错误抛出的语法错误,而且我似乎没有捕捉到它。
帮助我理解这里 SQLException 的确切含义,以及如何在不导致 RuntimeException 的情况下重现它并将其报告给客户端?
您的代码有误。您正在呼叫 update(PreparedStatementCreator psc)
, and as the name suggests, your code should create a fully "prepared" statement object, but it should not "execute" that statement, so remove the executeUpdate()
呼叫。
update()
调用抛出 DataAccessException
,而不是 SQLException
,因此 try
块中 SQLException
的唯一来源是您的 if
语句,所以你最好直接抛出 DataAccessLayerException
异常。不过,我建议改用 EmptyResultDataAccessException
。
由于Spring专门将已检查的SQLException
转换为未检查的DataAccessException
运行时异常,所以使用SpringJDBC时总是会出现运行时异常,并且这是一件好事,因为您现在不需要向代码中的所有方法添加已检查的异常。
未处理的异常由 Spring MVC 处理。默认情况下,Spring MVC 将重定向到错误页面。如果你不想要那个,请参见例如问题 Spring Boot Remove Whitelabel Error Page.