My short answer is "When possible, Yes".
I think it makes more sense to close the ResultSet in findRecords
. It has to be understood that executeQuery
returns a resource that has to be closed. There's no way around that. Since it is findRecords
that calls executeQuery
, I think it's cleaner to have it be responsible for closing the ResultSet that comes back from doing so, in fitting with the idea behind your question.
A general rule is to have each function have a single purpose as much as possible. findRecords
's purpose is to utilize a query to retrieve and process some data. mapResultToRecord
's purpose is to create a list of records by pulling them from a ResultSet. This all reads very nicely:
public List<Record> findRecords(String name) {
String query = prepareQuery(name);
ResultSet resultSet = executeQuery(query);
List<Record> result = mapResultToRecord(resultSet);
resultSet.close();
return result;
}
Look at it the other way (the way you have it). findRecords
's purpose it to prepare and execute a query, then hand it off to mapResultsToRecord
for continued processing. mapResultsToRecord
's purpose is to create a list of records from the results of a query made elsewhere, and then to dispose of the results of the query.
Doesn't the first story read a lot better than the second? Aren't the concerns better separated and defined by the first one than the second? Just my humble $.02 worth.
To further stress my point, I'd say that if you were going to leave it the way it is, you'd want to rename mapResultsToRecord
to mapResultsToRecordAndCloseResultSet
.
UPDATE: @JohnKugelman's great idea provides yet another reason that in findRecords
is the place to close the ResultSet. Only in here does it make sense to use a try-with-resource block, to get this alternative:
public List<Record> findRecords(String name) throws SQLException {
String query = prepareQuery(name);
try (ResultSet resultSet = executeQuery(query)) {
return mapResultToRecord(resultSet);
}
}
This version is guaranteed to close the ResultSet, even if mapResultToRecord
throws an exception. Note the throws SQLException
on the method signature. This is necessary because, even though you don't see the <ResultSet>.close()
call, it's there implicitly, and it can throw a SQLException.