Reputation: 161
I am developing an application with Angular and Spring with Java 7, however, I was asked to scan my code with SonarQube, so this tool is telling me that I need to apply a try with resources to close my Prepared Statement and Result Set, so I did some research and I implemented it like this:
try (Connection connection = DriverManager.getConnection(connectionUrl);
Statement statement = connection.createStatement();
PreparedStatement sentence = connection.prepareStatement(selectSql);
ResultSet resultSet = sentence.executeQuery();) {
// Create and execute a SELECT SQL statement.
sentence.setString(1, parametro);
logger.info(resultSet + " resultSet!----------------------------------------");
// Print results from select statement
while (resultSet.next()) {
logger.info(" Entro al While!----------------------------------------");
euroList.add(new EuroModel(resultSet.getInt("ID"), resultSet.getString("RFC"),
resultSet.getString("NOM")));
logger.info("recibiendo result-> " + resultSet.getString(2) + " " + resultSet.getString(3));
logger.info(euroList.toString());
}
} catch (SQLException e) {
logger.info("No se pudo conectar");
logger.info("EuroService");
logger.info("INFO: " + e);
List<EuroModel> empty = null;
return empty;
}
However, my code is not working due to the following line is in the wrong place and I don't know where should it be with this try with resources:
sentence.setString(1, parametro);
Could someone help me please?
Upvotes: 0
Views: 80
Reputation: 44355
You are executing your query before you have set your PreparedStatement’s parameter.
You can remove the ResultSet from your try-with-resources, because it will be closed automatically:
A
ResultSet
object is automatically closed when theStatement
object that generated it is closed, re-executed, or used to retrieve the next result from a sequence of multiple results.
You want to make sure you execute your PreparedStatement’s query, and obtain the corresponding ResultSet, after you have set your parameter:
try (Connection connection = DriverManager.getConnection(connectionUrl);
Statement statement = connection.createStatement();
PreparedStatement sentence = connection.prepareStatement(selectSql)) {
// Create and execute a SELECT SQL statement.
sentence.setString(1, parametro);
ResultSet resultSet = sentence.executeQuery();
logger.info(resultSet + " resultSet!----------------------------------------");
A useful additional lesson to take away from this: SonarQube is not an authority when it comes to good programming practices. In fact, SonarQube is wrong about things on a semi-regular basis.
This is such a case. Sonar is not smart enough to know that a ResultSet will be automatically closed when its parent Statement is closed. Sonar only knows that there is a closable object which doesn’t appear to be explicitly closed in the code.
As Slaw suggested, you can make Sonar happy by using another try-with-resources for the ResultSet:
try (Connection connection = DriverManager.getConnection(connectionUrl);
Statement statement = connection.createStatement();
PreparedStatement sentence = connection.prepareStatement(selectSql)) {
// Create and execute a SELECT SQL statement.
sentence.setString(1, parametro);
try (ResultSet resultSet = sentence.executeQuery()) {
logger.info(resultSet + " resultSet!----------------------------------------");
while (resultSet.next()) {
// etc.
}
}
Upvotes: 2