首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法解决close preparedsStatement的SonarQube错误

无法解决close preparedsStatement的SonarQube错误
EN

Stack Overflow用户
提问于 2019-09-16 19:00:18
回答 1查看 49关注 0票数 0

我有一个JDBCStreamTemplate类,它调用类中的另外两个方法- JDBCStreamRow和JDBCStreamResultSet。这两个类实现了Autoclosable。

JDBCStreamTemplate类方法有connection和preparedStatement。sql和连接的参数通过构造函数传递给JDBCStreamRow和JDBCStreamResultSet。

JDBCStreamRow和JDBCStreamResultSet类中的连接和PresparedStatement正在关闭。但是SONARQube给了bug连接和PreparedStatement需要在JDBCStreamTemplate类中关闭。

你能让我知道如何解决这个bug吗?

我试图通过在JDBCStreamTemplate中放入finally来关闭PS和CON,但它显示语句在任何预期的结果之前关闭。下面的代码是调用JdbcStreamResultSet构造函数的JDBCStreamTemplate类方法

代码语言:javascript
复制
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;
}
EN

回答 1

Stack Overflow用户

发布于 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,因此:

代码语言:javascript
复制
    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应该是满意的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57955425

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档