0

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();
   }
}
4
  • 5
    Help, a lot of kittens dies. You've declared dbConn and stmt as static. This code is definitely not threadsafe. I strongly recommend to redo the basic Java and JDBC tutorials. Commented Aug 11, 2010 at 18:48
  • 1
    You are also going to get SQLExceptions when you use the ResultSet, so you might as well propagate the exception. The ResultSet probably isn't going to work after the connection is closed. You might want to consider the Execute Around idiom. stackoverflow.com/questions/341971/… Commented Aug 11, 2010 at 19:10
  • 1
    FWIW: the normal practice is to map the ResultSet to a List<Entity> and return that instead. For some examples, head here and here. Commented Aug 11, 2010 at 19:14
  • 2
    Seriously, this is fine as an experiment for your own person learning, but don't put this on a live server or everything will break as soon as two people use it at the same time. :( Commented Aug 11, 2010 at 19:24

4 Answers 4

9

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
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

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.
You may want to add nullchecks as well.
4

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

1 Comment

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

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.

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.