Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 无法解决close preparedsStatement的SonarQube错误_Java_Jdbc_Sonarqube_Prepared Statement - Fatal编程技术网

Java 无法解决close preparedsStatement的SonarQube错误

Java 无法解决close preparedsStatement的SonarQube错误,java,jdbc,sonarqube,prepared-statement,Java,Jdbc,Sonarqube,Prepared Statement,我有一个JDBCStreamTemplate类,它调用类中的另外两个方法——JDBCStreamRow和JDBCStreamResultSet。这两个类实现了Autoclosable JDBCStreamTemplate类方法具有connection和preparedStatement。sql和connection的参数通过构造函数传递给JDBCStreamRow和JDBCStreamResultSet JDBCStreamRow和JDBCStreamResultSet类中的连接和预准备状态正在

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

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

JDBCStreamRow和JDBCStreamResultSet类中的连接和预准备状态正在关闭。但是SONARQube给了bug连接和PreparedStatement需要在JDBCStreamTemplate类中关闭

你能告诉我如何解决这个错误吗

我试图通过将finally放入JDBCStreamTemplate来关闭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;
}
但是SONARQube给了bug连接和PreparedStatement需要在JDBCStreamTemplate类中关闭

是的,很好的做法是,打开某个东西的代码也应该是负责关闭它的代码!在调用树上下分解该职责(即在一种方法中“创建/打开”,在另一种方法中关闭)会使跟踪控制流变得困难,因此会自找麻烦

JDBCStreamRow和JDBCStreamResultSet类中的连接和预准备状态正在关闭

另一件事是,我在代码中没有看到任何“关闭”的内容。您说在其他类中关闭了connection和preparedStatement,但是

a) 你也不会关闭其他的课程,而且

b) 我们没有这些的代码

所以。。。。。。。我将忽略您的其他类,而是确保在这段代码中关闭connection和preparedStatement

JDBCStreamRow和JDBCStreamResultSet。这两个类实现了Autoclosable

connection和preparedStatement都实现了AutoCloseable,所以希望您能够将我将要使用的相同思想应用到您自己的类中

了解如何使用
自动关闭
,这一点很重要。这并不意味着JVM在关闭对象时会自行做出任意决定。相反,这意味着当在try with resources块的“resources”部分中使用该对象时,该对象将被关闭

对于connection和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应该很高兴