Referenzprojekt Softwareentwicklung
Import von XML Daten in eine Datenbank
mit JAXB, HyperJAXB und Hibernate
Wenn komplexe XML-Daten in Access weiterverarbeitet werden sollen, stellt sich das Problem, dass Access nur eine sehr simple XML-Import-Schnittstelle bietet. Ein kompaktes Java-Modul erlaubt den vollständigen Import komplexer XML Daten in Access oder andere Datenbanksysteme
Hintergrund
Ca. 2000 XML-Dateien sollten in Access weiterverarbeitet werden. Die XML-Daten entsprachen einem festgelegten Schema, das in einer XML-Schema-Datei festgelegt war.
Umsetzung
Der zunächst nahe liegende Gedanke war, ein VBA-Programm zu schreiben, das die XML-Daten einliest. Dies wurde aber verworfen, weil VBA kaum XML-Funktionalitäten mitbringt; für jedes Element im XML-Schema hätte eigener Import-Code geschrieben werden müssen, das ganze System wäre groß und fehleranfällig geworden.
Stattdessen wurde eine Java-Lösung realisiert. Die Verwendung von Java im Zusammenhang mit Access wirkt zunächst fremd. Allerdings ist der Aufruf eines Java-Programms aus Access kein Problem, und die Vorteile der Lösung sind bestechend:
- Das Einlesen und Validieren von XML Daten ist von Java aus sehr einfach.
- Die Umsetzung eines XML-Schemas in Java-Klassen lässt sich mit erprobter und frei verfügbarer Software durchführen (JAXB).
- Mit Hibernate steht ein ebenfalls frei verfügbares Tool zu Verfügung, das es erlaubt, Daten aus Java-Klassen direkt in Datenbanken zu persistieren.
- Schließlich gibt es HyperJAXB, das die Verbindung zwischen Hibernate und JAXB herstellt: Es erzeugt die notwendigen Hibernate-Konfigurations- und Mapping-Dateien. Mit HyperJAXB wäre es auch möglich, aus Datenbank-Einträgen wieder XML Daten zu erzeugen, aber das war nicht Ziel dieses Projekts.
- Die Erzeugung der Tabellenstruktur in der Datenbank kann Hibernate automatisch übernehmen.
Der größte Vorteil dieser Lösung besteht darin, dass für den eigentlichen Datentransport keinerlei Code geschrieben werden musste. Durch die automatisierte Verarbeitung des XML-Schemas mit JAXB und HyperJAXB ist weitgehend sichergestellt, dass alle Daten aus den XML-Dateien 1:1 und ohne Verluste in der Datenbank ankommen. Das kann durch den Round-Trip-Test bewiesen werden: eine Rückkonvertierung von Datenbank-Daten in XML-Dateien ergibt wieder exakt dieselben Daten.
Eine Herausforderung bei dem Projekt war die Auswahl der richtigen HyperJAXB- und JAXB-Versionen. Version 3 von HyperJAXB verwendet Java Annotations für das Hibernate-Mapping, war im Zeitraum der Realisierung aber noch nicht offiziell freigegeben – allerdings sei es "so gut wie" fertig, war in einer Mailing-Liste zu lesen. Es funktionierte auch, allerdings ist die erzeugte Klassen- und damit auch Tabellen-Struktur sehr komplex. Wegen des speziellen Designs des fraglichen XML-Schemas wurden für jede 1:n Verknüpfung zwei(!) Verknüpfungstabellen erzeugt.
HyperJAXB 2 arbeitet anders und erzeugt von vornherein einfachere Datenstrukturen. Es gelang damit auch, bestimmte erzeugte überflüssige Verknüpfungs-Dateien zu eliminieren, sodass aus Benutzersicht in der Datenbank eine sinnvolle Datenstruktur ankam. Insgesamt benötigte das Fine-Tuning von HyperJAXB recht viel Forschung, die sich aber ausgezahlt hat.
Die andere Schwierigkeit erforderte ebenfalls etwas Recherche, konnte aber schneller gelöst werden: Hibernate bietet von Haus aus keine Unterstützung für Access. Für den reinen Zugriff auf die Datenbank wurde nach kurzen Tests mit der Pure-Java-Lösung HXXT, die nicht zufrieden stellend verliefen, die Java JDBC/ODBC-Bridge verwendet.
Dann ging es an die Entwicklung des Hibernate-Dialekts für Access. Es existieren im Netz einige Versuche dafür, keiner funktioniert aber richtig. Der Grund: Keine der in Hibernate primär unterstützten ID-Generierungs-Strategien funktioniert mit Access. "Identity" scheitert an Access' Unfähigkeit, "leere" Datensätze anzulegen (in der Art "INSERT INTO t ( ) VALUES ( )"), wobei eben ein Wert für die ID-Spalte belegt würde, wenn alle anderen Felder NULL sein dürfen. Die Lösung war dann einfach: Da wir konkurrierenden Zugriff auf die Access-Datenbank ausschließen können, wurde die Strategie "increment" gewählt, die einfach den höchsten Wert per SELECT abfragt und eins addiert.
Das Projekt wurde termingerecht und erfolgreich abgeschlossen und hat uns einige interessante neue Erkenntnisse verschafft.