我有一个JDBCStreamTemplate类,它调用类中的另外两个方法- JDBCStreamRow和JDBCStreamResultSet。这两个类实现了Autoclosable。
JDBCStreamTemplate类方法有connection和preparedStatement。sql和连接的参数通过构造函数传递给JDBCStreamRow和JDBCStreamResultSet。
JDBCStreamRow和JDBCStreamResultSet类中的连接和PresparedStatement正在关闭。但是SONARQube给了bug连接和PreparedStatement需要在JDBCStreamTemplate类中关闭。
你能让我知道如何解决这个bug吗?
我试图通过在JDBCStreamTemplate中放入finally来关闭PS和CON,但它显示语句在任何预期的结果之前关闭。下面的代码是调用JdbcStreamResultSet构造函数的JDBCStreamTemplate类方法
try {
Connection connection = DataSourceUtils.getConnection(this.getDataSource());
connection.setAutoCommit(false);
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setFetchSize(5000);
this.newArgPreparedStatementSetter(args).setValues(preparedStatement);
jdbcStreamResultSet = new JdbcStreamResultSet(qRef, connection, preparedStatement);
} catch (SQLException sqle) {
logger.error("{} JdbcStreamTemplate::streamResultSet: {}", qRef, JdbcUtilities.formatException(sqle));
throw sqle;
} catch (CannotGetJdbcConnectionException ce) {
SQLException sqle = new SQLException(ce.getMostSpecificCause());
logger.error("{} JdbcStreamTemplate::streamResultSet: {}", qRef, Helpers.getExceptionMessage(sqle));
throw sqle;
}
return jdbcStreamResultSet;
}发布于 2019-09-16 20:22:20
,但是SONARQube给了bug,连接和PreparedStatement需要在JDBCStreamTemplate类中关闭。
是的,打开某些东西的代码也应该是负责关闭它的代码,这是一个很好的实践!在调用树中上下拆分责任(例如,在一种方法中“创建/打开”,在另一种方法中关闭)使得跟踪控制流变得困难,这也是自找麻烦。
JDBCStreamRow和JDBCStreamResultSet类中的connection和PresparedStatement正在关闭。
另一件事是,我没有在你的代码中看到任何“关闭”的东西。您说正在关闭其他类中的connection和preparedStatement,但是
a)您也不会关闭其他类,并且
b)我们没有这些的代码,
所以..。我将忽略您的其他类,只需确保在此代码中关闭connection和preparedStatement。
JDBCStreamRow和JDBCStreamResultSet。这两个类实现了Autoclosable。
connection和preparedStatement都实现了AutoCloseable,因此希望您能够将我将要使用的相同思想应用到您自己的类中。
了解如何使用Autocloseable是很重要的。这并不意味着JVM在关闭对象时会自己做一个武断的决定。相反,这意味着当在try-with-resources块的"resources“部分中使用该对象时,该对象将被关闭。
对于连接和preparedStatement,这意味着我们可以将您的代码更改为使用try-with-resources,因此:
try ( Connection connection = DataSourceUtils.getConnection(this.getDataSource());
PreparedStatement preparedStatement = connection.prepareStatement(sql);
)
{
connection.setAutoCommit(false);
preparedStatement.setFetchSize(5000);
this.newArgPreparedStatementSetter(args).setValues(preparedStatement);
jdbcStreamResultSet = new JdbcStreamResultSet(qRef, connection, preparedStatement);
} catch (SQLException sqle) {
logger.error("{} JdbcStreamTemplate::streamResultSet: {}", qRef,
JdbcUtilities.formatException(sqle));
throw sqle;
} catch (CannotGetJdbcConnectionException ce) {
SQLException sqle = new SQLException(ce.getMostSpecificCause());
logger.error("{} JdbcStreamTemplate::streamResultSet: {}", qRef, Helpers.getExceptionMessage(sqle));
throw sqle;
}
return jdbcStreamResultSet;
}使用这种布局,无论发生什么情况,连接和preparedStatement都会被保证关闭(并且以正确的顺序)-并且SONARQube应该是满意的。
https://stackoverflow.com/questions/57955425
复制相似问题