Hibernate Spatial ist ein Paket, das die objektrelationale Handhabung von geometrischen und geographischen Datentypen ermöglicht und mit einer Vielzahl von Datenbanken (Oracle, DB2, MySQL, SQL Server…) verwendet werden kann. Die folgenden Beispiele wurden mit einer MariaDB 10.4 auf einem Wildfly 15-Server getestet.
1. Einrichtung
Um die Funktionalitäten von Hibernate Spatial zu verwenden, müssen folgende Abhängigkeiten in der pom.xml eingefügt werden:
Die dom4j-Abhängigkeit musste explizit eingebunden werden, da es ansonsten beim Deployment auf dem Server zu einer ClassCastException kam:
java.lang.ClassCastException: class org.dom4j.DocumentFactory cannot be cast to class org.dom4j.DocumentFactory
In der persistence.xml muss als Datenbank-Dialekt noch ein spezieller Dialekt aus dem Hibernate Spatial Paket angegeben werden:
2. Beispiele mit dem vividsolutions.jts-package
Mit dem jts-package von Vivid Solutions können einfache geometrische Figuren wie Punkte, Linien und Vielecke als Java-Objekte erstellt werden. Sie erben alle von der Vaterklasse Geometry und können über die sogenannte well known text (WKT) Repräsentationüber einen WKTReader initialisiert werden. Die folgende Zeile erstellt zum Beispiel einen Punkt im Ursprung:
Eine Linie und ein Vieleck lassen sich wie folgt erzeugen:
Beim Vieleck müssen der erste und der letzte Punkt übereinstimmen, damit ein korrektes, geschlossenes Vieleck erzeugt wird.
Man kann nun eine einfache Entity erstellen, die ein Point-Objekt enthält:
Analog können auch eine LineStringEntity und eine PolygonEntity erstellt werden. Die jts-Objekte werden in der MariaDB als Geometry-Felder abgespeichert, das die well known binary (WKB) Repräsentation der Objekte enthält, also die binäre Entsprechung der WKT-Repräsentation.
3. Queries über die Geometrie-Objekte
Interessant sind schließlich die Queries mit speziellen Funktionen, die die räumlichen Beziehungen der Objekte miteinbeziehen. Der MySQL-Dialekt von Hibernate kennt hier folgende Funktionen: within, contains, crosses, overlaps, disjoint, intersects, touches und equals. Eine Beschreibung dieser Funktionen lässt sich der Hibernate Spatial sowie der MariaDB-Dokumentation entnehmen. Interessanterweise wird die Funktion distance im MySQL-Dialekt nicht unterstützt, auch wenn sowohl Hibernate Spatial als auch die MariaDB diese Funktion prinzipiell unterstützen.
Zunächst werden einige Points und LineStrings in der Datenank angelegt:
In den entsprechenden Methoden wird jeweils eine PointEntity bzw. LineStringEntity angelegt und mit dem geometrischen Objekt gefüllt, das der WKT-Repräsentation des Parameters entspricht, und schließlich persistiert.
Die Möglichkeiten von Hibernate-Spatial sollen nun an einigen Beispiel-Queries illustriert werden. Man kann beispielsweise die Punkte laden, die auf einer bestimmten Linie liegen:
Diese Query liefert die beiden Punkte „POINT (3 2)“ und „POINT (2 0)“ zurück.
Weiterhin lassen sich die LineStrings laden, die sich mit einem bestimmten anderen LineString schneiden:
Diese Query liefert einen LineString zurück: „LINESTRING (1 1, 4 1, 4 6)”.
Mit der Funktion within lässt sich überprüfen, welche Punkte innerhalb eines anderen Objektes liegen, im folgenden Beispiel z.B. innerhalb eines Vielecks:
Diese Query liefert die Punkte „POINT (3 2)“ und „POINT (2 0)“ zurück.
4. Einschränkungen:
Die hier gezeigten geometrischen Objekte liegen alle in einem zweidimensonialen kartesischen Koordinatensystem. Um geographische Daten zu speichern, müsste man hier mit den üblichen geographischen Einheiten (Längen- und Breitengrad) arbeiten. Für die Beziehung zwischen den einzelnen Punkten und Figuren müssen dann andere Funktionen verwendet werden, weil es sich dann um eine sphärische Geometrie handelt. Diese Funktionen werden leider bisher aber nicht von Hibernate Spatial unterstützt, so dass die Anwendung in diesem Fall nur eingeschränkt möglich ist.