I am wondering if the following code uses the try-with-resources correctly.
try (ResultSet rs = new QueryBuilder(connection, tableName(), getPaths(), searchQuery()).add(constraint).build().executeQuery()) {
while (rs.next()) {
beans.add(createBean(rs));
}
}
The arguments are not important, the only important thing is:
new QueryBuilder().build();
returns aPreparedStatement
.
I completely understand that rs
will be closed, but will the PreparedStatement
also be closed, and if so, for what reason? Because the ResultSet
closes or because of the try-with-resources?
You can include several resources in the try, and they will all be closed - which is necessary if you want the
PreparedStatement
to be closed:As you correctly stated,
rs
will be closed. This means actually that theclose()
method will be invoked onrs
. So the try-with-ressource statement doesn't explictly close thePreparedStatement
in your case.If it's closed otherwise (in context of the
rs.close()
) is kind of hard to say without knowing the implementation ;-)EDIT
As @TheNewIdiot correctly found out, your
PreparedStatement
won't be closed.According to the documentation here - tryResourceClose, as I read it, it is specific to resources that are
declared
.The try-with-resources statement is a try statement that declares one or more resources.
Reading further down you see:
You may declare one or more resources in a try-with-resources statement. The following example retrieves the names of the files packaged in the zip file zipFileName and creates a text file that contains the names of these files:
I suggest the correct answer to you issue is the following:
PreparedStatement#close() will automatically close any associated result sets but the reverse is not true because statements are reusable after their result sets are closed.
Look at the javadoc of ResultSet#close():
And then Statement#close():
This usage looks very crappy to me :
If executed enough times it will leak all of the available cursors, because cursors are associated with the
Statement
not withResultSet
.Hence to close the underlying
PreparedStatement
with try-with-resources statement , just declare it within thetry
statement :Look at this answer from assylias, declare the
PreparedStatement
as well asResultSet
inside thetry
statement.Since you are not looking for a memory leak, but a resource leak . The memory of the
PreparedStatement
will be collected eventually and it's memory freed, as it is not referenced anymore after execution of your method given the way it is initialized , however, the resources hold by theStatement
is not closed .