The theory of checked exceptions is simple.
When designing an interface, consider the exceptional cases that can and will happen with the normal state of the method call. Declare these exceptions in your interface, as the programmer will have to deal with them directly.
For example, a bank account withdrawal method may throw an OverdraftException, which is the expected exception - the output may fail due to overdraft, but this type of failure can be handled differently using the client code (you can decide to completely refuse another, can decide to apply a huge fine and allow the recording of a negative balance, another may decide that their client is allowed to draw from another account).
However, runtime exceptions should have been programming errors that should not have been handled directly - for example, NullPointerExceptions, which occur only if the methods accept invalid arguments or do not check for such cases directly.
This is a good theory. However, Java ruined the implementation of Exceptions, and it threw the book of this theory out of the window.
There are two cases that I will illustrate where Java messed up its implementation of Exception. These are IOException and SQLException.
An IOException occurs anytime, anywhere, when a thread in a Java IO library gets tangled up. However, this is a proven exception. But as a rule, you can do nothing except the journal, that an error occurs - if you just write to the console, what can you reasonably expect if you suddenly get an IOException when writing?
But there is more.
An IOException also hides things like file exceptions and network exceptions. They may be subclasses of IOException floating for this, but this is still an exception. If your letter to an external file fails, you cannot really do much if your network connection is disconnected, the same.
SQLException is the same. Exception names should indicate what happened when they are called. SQLException is not. A SQLException is thrown every time there is any possible number of errors when working with a database - the MOST THAT YOU DO NOT NEED TO DO WITH SQL.
Therefore, programmers are usually annoyed by exception handling and let Eclipse (or any other IDE that they use) create blocks like this:
try { thisMethodThrowsACheckedExceptionButIDontCare(); } catch(Exception e) { e.printStackTrace(); }
However, with RuntimeExceptions, they intentionally fail and are eventually processed by the JVM or container level. This is a good thing - it causes errors to be displayed, and then you have to fix the code directly, and not ignore the exception - you can still just print the stack trace (I hope that it will write it, and not print to the console directly), but then there will be an exception handler that you were forced to write because of the real problem - not because the method said that it could throw an exception, but what it did.
Spring uses a DataAccessException to throw SQLExceptions, so you don't need to treat them as a checked exception. As a result, the code becomes much cleaner - if you expect a DataAccessException, you can handle it, but most of the time you allow it to propagate and register as an error, because your SQL should be debugged by the time your application is released, which means that DataAccessException is probably is a hardware problem that you cannot solve - DataAccessException is a much more meaningful name than SQLException, because it shows that access to the data failed - not that your SQL query was to blame.