21.8Die Ausnahmen bei JDBC, SQLException und Unterklassen
Normale Throwable-Ausnahmen in Java tragen lediglich eine Nachricht, die sich mit getMessage() erfragen lässt. Da bei Datenbanken aber viele Dinge schiefgehen können, hätten die Architekten der JDBC-API viel zu tun, wenn sie für jede mögliche Ausnahme eine Exception-Klasse bereitstellen wollten. Doch wegen der schier unüberschaubaren Anzahl an Fehlern haben sie sich für ein anderes Modell entschieden.
21.8.1JDBC-Fehlerbasisklasse SQLException
Zunächst einmal gibt es für JDBC-Ausnahmen den Basistyp SQLException. Zusätzlich speichert jedes SQLException-Objekt Fehlercodes, die der JDBC-Treiber der Datenbank setzen und so über den konkreten Fehler informieren kann.
Die genauen Informationen einer SQL-Ausnahme sind über drei Methoden zugänglich:
String getMessage(): eine textuelle Beschreibung des Fehlers
String getSQLState(): Einen String mit dem SQL-Status. Hier gibt es zwei Konventionen. Einmal kann es ein SQL-Status nach der SQL-CLI-Spezifikation der Open Group (vor über zehn Jahren hieß sie X/Open) sein – oder ein SQL:2003-Code. Beide sind datenbankunabhängig. Nach welcher Spezifikation der Code formuliert ist, sagt die Methode getSQLStateType() vom DatabaseMetaData-Objekt. Der Open-Group-Standard ist üblich.
int getErrorCode(): Einen Fehlercode vom JDBC-Treiber. Er kommt vom Hersteller der Datenbank bzw. vom Datenbanktreiber. Er ist datenbankabhängig.
Der Open-Group-SQL-Status ist eigentlich eine Zahl, aber als String verpackt. Im Optimalfall ist der Code »00000«, was »alles paletti« heißt. Die ersten beiden Ziffern stehen für die Fehlerklasse. 01 ist eine Warnung, 02 sagt, dass Daten fehlen, usw.[ 150 ](Unter http://pic.dhe.ibm.com/infocenter/db2luw/v9r7/index.jsp?topic=%2Fcom.ibm.db2.luw.messages. doc%2Fdoc%2Frdb2stt.html bekommen Leser einen Überblick.)
Eine Verkettung unglücklicher Tatsachen
Eine SQLException hat eine Besonderheit, die sonst keine Ausnahme in der Java-Bibliothek aufweist. Sie implementiert die Schnittstelle Iterable<Throwable>:
extends Exception
implements Iterable<Throwable>
Das heißt, dass eine SQLException ein Bündel von Ausnahmen repräsentieren kann und nicht nur genau eine. Welche JDBC-Ausnahmen noch an der SQLException hängen, liefert getNextException() bzw. steckt im Iterator der SQLException.
[zB]Beispiel
Laufe alle Fehler ab:
catch ( SQLException e ) {
for ( ; e != null; e = e.getNextException() ) {
System.err.println( "Message: " + e.getMessage() );
System.err.println( "SQL State: " + e.getSQLState() );
System.err.println( "Error Code: " + e.getErrorCode() );
}
}
21.8.2SQLWarning
Nicht jeder Fehler bzw. jede Meldung der Datenbank ist gleich ein kritischer Fehler, der zum Abbruch der Datenbankoperationen führt. Die JDBC-API bietet mit der Klasse SQLWarning eine besondere Unterklasse von SQLException, doch wird sie nicht als Exception ausgelöst, sondern muss im Programm explizit über getWarnings() geholt werden. Die Typen Connection, ResultSet und Statement deklarieren diese Operation. Im besten Fall holen sich Entwickler alle Warnungen und loggen sie.
Da die SQLWarning eine SQLException ist, ist auch die Verarbeitung von SQL-Code und Fehlercode gleich. Anstatt jedoch mit getNextException() zu arbeiten, bietet SQLWarning die Methode getNextWarning(), um zur nächsten Warnung vorzustoßen. Werden die Meldungen nicht geholt, dann werden sie bei der Ausführung der nächsten SQL-Anweisung gelöscht.
Abbildung 21.6Vererbungshierarchie der JDBC-Fehlerklassen
Daten fehlen
Für die SQL-Status »01004« und »22001« gibt es eine eigene Fehlerklasse, die DataTruncation. Sie ist ein spezieller Typ einer SQL-Warnung und wird immer dann erzeugt, wenn Daten während der Schreib- oder Leseoperationen verloren gingen. Die Meldung wird genauso geholt wie SQLWarning, nur wird mittels instanceof DataTruncation überprüft, ob es sich um DataTruncation handelt. Dies erfordert eine Typumwandlung von SQLWarning auf DataTruncation. Dann stehen Methoden wie getIndex() oder getTransferedSize() bereit, die aussagen, für welche Spalte wie viel Bytes korrekt übertragen wurden. DataTruncation ist die einzige Unterklasse von SQLWarning.