Why is SQLException a checked exception

Bohemian picture Bohemian · May 14, 2013 · Viewed 21.7k times · Source

Can anyone think of a rational reason why SQLException is a checked exception?

Yes, there could be a syntax error in the query
Yes, the connection might have died
Yes, there might be a permission problem
Etc, etc blah blah blah

But practically 100% of the time (once you're running in production), there isn't any problem.

If there is a problem, the calling code can't do anything to recover, so for that reason it should be unchecked.

Being checked create masses of perfunctory try catch blocks throughout the code, as anyone who has been involved with a project that uses JDBC will attest. The code clutter is significant.

Because of the esoteric nature of SQL, the myriad of reasons you may get an SQLException and their complexity means you basically can not recover, unless the exception is caused by temporary network problem, but even then in a synchronous call, you're sunk anyway because you can't wait indefinitely for the network problem to be resolved, so you're going to have to fail the transaction.

Typically, calling SQL looks like this:

try {
    // make some SQL call(s)
} catch {SQLException e) { 
    // log the exception
    return; // and give up
}

Such code adds no value. There nothing reasonable you can do to recover. You might as well let a runtime exception bubble up - ie SQLException should be a runtime (unchecked) exception.

Answer

user1930502 picture user1930502 · May 14, 2013

practically 100% of the time there isn't any problem - This is limited to your own observation which says nothing about other systems. There are various computer systems around the world with various bottlenecks. Your success rate is almost 100%. Others have to deal with much lower percentage.

Common misconception is to consider introducing/removing a Checked Exception by frequency of its occurrence. Checked exceptions serve as communication channels. As you know, every method has its public interface. This way, method tells us which arguments it accepts and what is result of the code in its body.

When it becomes impossible for a method currently being in progress to keep its promise (e.g. returned value) it needs a way to tell the other method that something went wrong and it can't do what was expected. But how to do it ? Sending the message as the value returned doesn't work, there is almost no chance for the calling method to distinguish between proper value and an error message. Not to say some methods have void as a return value. So what do you do when you're unable to keep your promise defined by your method's interface ? Well, you throw an exception (send a message).

If you expect ResultSet and there is no connection to your database established, what should you do ? Return empty ResultSet ? Hell no, this tells us that the database is empty. Return null ? Well, this only delegates the problem and makes finding the cause unclear.

You could use that empty resultset and make it a part of another query to another database, making it inconsistent.

Without SQLException, even one mistake could lead to data inconsistency.