Wenn ich in einer Quarkus Anwendung eine relationale Datenbank integrieren möchte, geht der Weg meistens über Jakarta Persistence für das Objekt-Relationale-Mapping. Als Implementierung wird dann Hibernate ORM eingesetzt. Das ist soweit auch nachvollziehbar, da es den Jakarta EE Standard nutzt.
Da Jakarta Persistence im Standard allerdings nur wenige Funktionen für die Persistierung von Daten bereitstellt, haben sich Erweiterungen wie Panache oder auch Jakarta Data entwickelt, um diese Standardfunktionalitäten ohne Implementierungsaufwand bereitzustellen.
Neben diesen Erweiterungen gibt es aber noch weitere, die für einen Einsatz im Zusammenhang mit einer relationalen Datenbank infrage kommen. Um diese Vielfältigkeit der Möglichkeiten zu vereinheitlichen wurde Quarkus Data eingeführt. Hiermit werden sämtliche Aspekte für den Einsatz von relationalen Datenbanken unter einem Begriff zusammengefasst.
Entitäten
In Quarkus Data kann als Basis das Active-Record-Pattern verwendet werden. Damit werden alle Funktionalitäten für die Änderung an den Entitäten innerhalb der Klasse bereitgestellt. Um aus einer Entität eine aktive Entität zu machen, müssen wir lediglich von der Klasse PanacheEntity ableiten und die Attribute public machen.
@Entity
public class Person extends PanacheEntity {
public String firstname;
public String lastname;
}
Die Entität enthält keinen Identifier, im Standard wird mit PanacheEntity eine auto-generierte Id als Typ Long mitgeliefert. Wenn man das nicht möchte, gibt es natürlich die Möglichkeit die Verwaltung der Id selbst zu übernehmen.
Wir können damit unsere Entität mit Daten befüllen und auf der DB speichern.
Person person = new Person();
person.firstname = "John";
person.lastname = "Doe";
person.persist();
Repositories
Möchte man über die Basis-Funktionalitäten der Entität hinaus Abfragen ausführen, ist es möglich eine Repository-Klasse mit den grundlegenden Zugriffsmethoden erzeugen zu lassen. Im Tutorial wird dieses Repository als inneres Interface in der Entität definiert. Ich bin eher ein Freund der strikten Trennung, daher erstelle ich ein eigenständiges Interface.
public interface PersonRepository extends PanacheRepository<Person> {
@Find
Person findByName(String name);
@HQL("delete from Person where name = :name")
long deleteByName(String name);
}
Wie wir im oberen Beispiel sehen, ist es ebenfalls möglich über einfache Methoden-Definitionen weitere Funktionalitäten implementieren zu lassen. Mit der Annotation @Find werden Datenbankabfragen formuliert, die automatisch eine Where-Bedingung der übergebenen Parameter beinhalten. Mit der Annotation @HQL ist es möglich eigene Abfragen mit Hilfe der HQL zu erstellen.
Ein großer Vorteil bei der Verwendung der klassischen Hibernate ORM Implementierung ist die Nutzung einer stateful-Session. Damit kann ich ganz bequem den Persistence Context für die Synchronisierung zur Datenbank nutzen. Solange sich die Entität im Persistence Context befindet wird sie automatisch mit der Datenbank abgeglichen. Wer lieber eine stateless-Session nutzen möchte kann dies natürlich auch tun.
Fazit
Mit der Vereinheitlichung der Möglichkeiten bei der Nutzung einer relationalen Datenbank mit Quarkus wurden die meisten Varianten berücksichtigt. Ein Entwickler muss sich nun keine Gedanken mehr machen, ob er Hibernate ORM mit Panache einsetzen möchte, oder doch lieber das Hibernate ORM in einer reaktiven Version. Auch der neue Standard Jakarta Data wird innerhalb von Quarkus Data unterstützt. Es ist zwar nur eine Benennung und die Zusammenfassung einiger Extensions, aber ein wichtiges Zeichen in Richtung der Entwickler, dass deren Bedürfnisse wahrgenommen wurden.






