chained java.lang.SQLException instances vs. Throwable#getCause

java, jdbc

Solution

The `SQLException.setNextException(Exception)` and `SQLException.getNextException()` allows for multiple distinct `SQLException`s to be reported back from a single method invocation. Those `SQLException`s are not each others cause.

The actual occurrence is pretty rare, but say that I execute a prepared insert statement with 2 parameters. One of those parameters is too long, and another is null while the column is `NOT NULL`. A database could (although I believe most databases won't) report both errors back to the driver. But as the `executeUpdate` method can only throw a single `SQLException`, these errors are chained together using `setNextException`. This then allows you to find out both error conditions

Also note that `SQLException` has an `iterator()` method which allows you to iterate over each `SQLException` and their causes (ie: the current `SQLException`, all causes of the current `SQLException`, the next `SQLException` if any etc.

It is similar to the use of `getNextWarning()` for `SQLWarning` if multiple warnings occurred (either concurrent or sequentially), they are chained together. `SQLWarning` is not thrown, but made available on the object that generated the warning (eg `Connection.getWarnings()`, `Statement.getWarnings()` etc). This method returns the first warning, and allows you to discover the additional warnings using `getNextWarning()`.

Problem

What are the semantics behind a "chain" of SQLException objects and how is this different from the similar (implicit) chain that's formed by the `getCause` method on the `Throwable` class? Since a `SQLException` is also a `Throwable`, an instance of that class can have two such "chains: - one defined by a sequence of `getNextException()` calls - till null is ultimately returned - the other defined by a sequence of `getCause()` calls - till null is ultimately returned ... in such a case how would these two chains relate to each other?

Original source