Gabi und Sascha
Kategorien : Alle | Berlin | Bücher | Fotografie | Java | Linkhalde | Weichware | Verfassung

Java 1.5 bringt wirklich einige schicke neue Features mit. Dabei spreche ich nicht einmal von Generics des JSR 14, das ist ein nice to have. Spannend sind vielmehr die Monitoring und Management Fähigkeiten und die im JSR 114 definierten RowSet-Erweiterungen. Diese sind sehr spannend für das behandeln grosser Datenmengen im J2EE Umfeld.

RowSets sind dabei als JavaBean definiert. Beans lassen sich serialisieren, indem sie z.B. das Serializable Interface implementieren. Hierdurch ist es möglich sie z.B. mittels RMI zu verschicken.

Ein auf RowSet aufbauendes Interface beschreibt das CachedRowSet. Dieses wird als sogenanntes disconnected RowSet bezeichnet, da es für das Liefern der Daten nicht mit einer Datenbank verbunden sein muss. Dies ermöglicht eine recht einfache Implementierung des Value List Handler Pattern.

Use case: Ein Querysprachenanfrage eines Clients wird auf dem Business Tier (Session Bean) in SQL übersetzt und an eine relational Datenbank geschickt. Die Ergebnisse werden in kleine Einheiten zerlegt, damit der Client in einer Webseite die Ergebnisse in z.B. 10er Schritten anzeigen kann. Damit wird zum Einen der Benutzer nicht mit einer unüberschaubaren Datenmenge erschlagen und es kommt zum Anderen auch nicht zu OutOfMemory Ausnahmen. Das CachedRowSet wird auf dem Server zwischengespeichert. Ruft der Client jetzt die nächsten 10 Ergebnisse ab, so wird das CachedRowSet des Servers verwendet und nextPage() aufgerufen. Diese Methode sorgt dann dafür, dass in dem CachedRowSet die nächsten 10 Einträge aus der Datenbank abgelegt werden. Das ganze wird wiederum zum Client geschickt. Da zwischen den Aufrufen der Methoden des CachedRowSets keine Datenbankverbindung bestehen muss, wir hierbei von einem disconnected RowSet gesprochen.

Dieser Anwendungsfall funktioniert leider nicht problemlos mit der Referenzimplementierung für das Package javax.sql.rowset. Problematisch ist das Serialisieren der Instanz. Die Referenzimplementierung versucht z.B. auch das ResultSet innerhalb des Objektes zu serialisieren, da dieses nicht als transient gekennzeichnet ist. Mir zur Zeit allerdings keine ResultSets bekannt, welches serialisierbar sind. Das funktioniert also nicht.

Alternativ können die Ergebnisse natürlich mittels eines Transfer Object Assembler umgepackt werden. Dabei werden die Werte aus dem RowSet ausgelesen und in einem ValueObject verpackt zum Client transportiert.

Allerdings ist diese Lösung noch immer nicht clustersicher. Um den Sessionzustand auf einen anderen Rechner im Clusterverbund zu propagieren, muss das CachedRowSet Objekt serialisierbar sein.

Sucht man im Internet ein wenig, dann findet man sehr schnell andere Hersteller wie z.B. Oracle oder i-net, die CachedRowSet Klassen anbieten. Diese lassen sich auch korekt mit ihren jeweils unterstützten ResultSets serialisieren. Allerdings implementieren diese Klassen nicht CachedRowSet aus dem JDK 1.5 und unterstützen damit bisher auch nicht den Pagingmechanismus. Schade, schade....

Da fällt es eigentlich nur noch sehr wenig auf, dass das JDK 1.5 zwar eine Schnittstelle für die unterschiedlichen Implementierungen mit einem ausführlichen Vertrag anbietet, aber es leider keinen Mechanismus gibt entsprechende Implementierungen einfach einzubinden. Hier muss man dann wieder hart gegen die Klasse eines Anbieters (un sei es nur Sun) programmieren... Okay, das kann man natürlich auch durch eine Factory kapseln, wie es beispielsweise Bea im Weblogic 9.0 macht. Da braucht man dann allerdings eine Fabrik für die Fabrik, um plattformunabhängig zu bleiben. Kann man machen.

Alles in allem herscht bei den CachedRowSets noch ein erhebliches Durcheinander und es wird noch einige Zeit dauern, bis Licht am Ende des Tunnels auftaucht. Vielleicht muss man doch erst einmal wieder selbst einen Datenbankcursor bemühen.

Eine interessante Diskussion zu dem Thema findet sich übrigens auch auf TheServerSide.com.