views:

116

answers:

4

I'm Java beginner, but I thought that when using try-catch-finally I don't have to declare the exception using throws SQLException. However if I don't use it the compiler gives me the error: "unreported exception java.sql.SQLException; must be caught or declare to be thrown". I included a catch so I'm not sure why this errors occurs.

public static ResultSet getResultSet ( String query ) 
{
    dbConn = getConnection();

    try
    {
       stmt = dbConn.createStatement( );

       ResultSet rs = stmt.executeQuery( query );

       return rs;
    }
   catch (SQLException ex)
   {
       return null;
   }
   finally
   {
       stmt.close();
       dbConn.close();
   }
}
+8  A: 

It's because the close() methods:

stmt.close();
dbConn.close();

may throw SQLException and you haven't encapsulated them in a try/catch block.

A method may very well throw an exception from within a finally-clause, and, with no catch-clause handling those exceptions, the method must be declared to throw those exceptions.

Basically, you need to do something like

finally
{
    try {
        stmt.close();
    } catch (SQLException sqle) {
        // log the statement-close exception
    }

    try {
        dbConn.close();
    } catch (SQLException sqle) {
        // log the connection-close exception
    }
}
aioobe
No, basically you need to put each `close()` in **its own** `try-catch` which is logging or ignoring the exception. In your example, if `stmt.close()` throws, then `dbConn.close()` will never take place.
BalusC
ah, good point. I'll update :)
aioobe
You may want to add nullchecks as well.
BalusC
+4  A: 

Put dbConn = getConnection(); in the try section. It can throw an SQLException too.

Adam
That seems another homegrown static method. He might already have suppressed that exception inside the method (which is indeed a bad idea btw).
BalusC
+2  A: 

Aside from the compiler errors, this code will fail at runtime.

When you close the Connection from which the ResultSet is created, the ResultSet will be invalidated, and any calls on it will fail. (Sure, some strange JDBC driver be implemented so that this could work, but this is incorrect usage of the JDBC API.)

The scope and lifetime of the ResultSet can't be any wider than its parent Connection and Statement.

erickson
A: 

The code you've written uses a class that has a type of exception that must be handled. You can do that in one of two ways, by passing it up the chain i.e. re-throwing the exception, or by actually handling it as some of the other comments show by putting the close methods in a try catch of there own in the finally block.

Typically you will see these in file IO classes where you should always close the object or stream to ensure you leave it in a valid state. Otherwise you are leaving it up to the Operating System to clean up for you.