IIRC, JDBC has the concept of a causal chain (which all Java exceptions now have) and it also has the concept of a list of exceptions not related to each other. The typical use case for the latter is warnings about rows rejected during a load, or rows that had arithmetic exceptions during query processing.
I think of SQLException.getCause() as an "upwards" link and SQLException.getNextException() as as "sideways" link. The chain of exceptions by getNextException() must all be instances of SQLException.
I would ignore for now the possibility that the cause of a SQLException is itself a SQLException that is part of a chain. Thus the structure looks like this:
e1c1 e3c1 e4c1
| | |
e1 ------ e2 ------ e3 ------ e4
I think I'd model the chain of exceptions from a statement as a list of exceptions, and each exception has a "cause" field which is either null or a serialized copy of the getCause() exception.