TL; dr
- In theory, closing a statement closes the result set.
- In practice, some erroneous implementations of the JDBC driver, as you know, could not do this. Therefore, the advice from your instructor, which she learned at the school of hard knocks. If you are not familiar with every implementation of every JDBC driver that can be deployed for your application, use try-with-resources to automatically close every level of your JDBC job, such as statements and result sets.
Use try-with-resources syntax
None of your codes make full use of try-with-resources . In the try-with-resources syntax, you declare and instantiate Connection , PreparedStatement and ResultSet in brackets in front of the brackets. See the tutorial for Oracle .
Although your ResultSet is not explicitly closed in your last code example, it should be closed indirectly when its statement is closed. But, as described below, it cannot be closed due to a faulty JDBC driver.
AutoCloseable
Any such objects that implement AutoCloseable will be automatically called by their close method. So there is no need for these finally clauses.
Yes, for the liberal arts professions reading this, yes, the Java team wrote with the error "shut down."
How do you know which objects are automatically closed and which are not? Look at the documentation for their class to see if it AutoCloseable as a superinterface. Conversely, see the JavaDoc page for AutoCloseable for a list of all related subinterfaces and implementing classes (actually dozens).
For example, to work with SQL, we see that Connection , Statement , PreparedStatement , ResultSet , and RowSet all automatically close, but there is no DataSource . This makes sense because the DataSource stores data about potential resources (connections to the database), but is not a resource itself. DataSource never "open", so there is no need to close it.
See Oracle Tutorial, Resource Statement .
Code example
Your last code sample comes close to good, but it should have wrapped the ResultSet in a try-with-resources statement to automatically close it.
Quote ResultSet JavaDoc:
The ResultSet object is automatically closed when the Statement object that generated it is closed, re-executed, or used to obtain the next result from a sequence of multiple results.
As your teacher suggested, some JDBC drivers had serious flaws that did not meet the promise of the JDBC specification to close the ResultSet when its Statement or PreparedStatement closed. So many programmers have the habit of closing every ResultSet object explicitly.
This additional responsibility is made easier by the try-with-resources syntax. In real life, you will likely have to try all of your AutoCloseable objects, such as ResultSet . So my own opinion is this: why not try it with other resources? It will not hurt, makes your code more self-documented about your intentions, and it can help if your code ever encounters one of these faulty JDBC drivers. The only price is a pair of guys , provided that in any case you have the opportunity to try other things.
As indicated in the Oracle AutoCloseable , several AutoCloseable objects declared together will be closed in the reverse order , as we would like.
Tip: The try-with-resources syntax allows an optional semicolon in the last declared resource element. I use the semicolon as a habit, because it is easy to read by eye, consistent and easy to edit. I have included it in your PreparedStatement s2 line.
public void doQueries() throws MyException{ // First try-with-resources. try ( Connection con = DriverManager.getConnection( dataSource ) ; PreparedStatement s1 = con.prepareStatement( updateSqlQuery ) ; PreparedStatement s2 = con.prepareStatement( selectSqlQuery ) ; ) { … Set parameters of PreparedStatements, etc. s1.executeUpdate() ; // Second try-with-resources, nested within first. try ( ResultSet rs = s2.executeQuery() ; ) { … process ResultSet } catch ( SQLException e2 ) { … handle exception related to ResultSet. } } catch ( SQLException e ) { … handle exception related to Connection or PreparedStatements. } }
I assume that there is a more elegant syntax for this kind of work that could be invented in a future programming language. But for now, we have a try with resources, and I use it happily. Although the attempt to use resources is not entirely elegant, it is significantly better than the old syntax.
By the way, Oracle recommends using the DataSource implementation to get connections, rather than the DriverManager approach, which can be seen in your code. Using a DataSource throughout the code makes it easy to switch drivers or switch to a connection pool. See if your JDBC driver provides a DataSource implementation.
Update: Java 9
Now in Java 9 you can initialize resources before trying with resources. See this article . This flexibility may be useful in some scenarios.