Spring Repositories

Grundlagen

Als Entwurfsmuster für die Verbindung zwischen persistenten Klassen und einer Datenbank hat sich das DAO-Pattern (Wikipedia, Oracle) etabliert. Dabei steht für jede Klasse oder zumindest für jede Klassenhierarchie ein Datenzugriffsobjekt (Data Access Object, DAO) zur Verfügung. Dieses stellt mindestens die üblichen CRUD Methoden zum Speichern, Lesen und Löschen von Objekten bereit. Weitere sinnvolle Funktionalitäten sind Suchen, Sortieren oder Bildung von  Teilmengen. Zur Performance-Optimierung kann es sinnvoll sein, weitere komplexere Datenbankoperationen im DAO zu implementieren, die beispielsweise mit einer Query einen ganzen Objektgraph in den Speicher laden.

Spring Repositories

Standardmethoden

Spring Data stellt Integrationsschnittstellen für eine Vielzahl von Datenhaltungssystemen zur Verfügung. Im Beispielprojekt und in diesem Tutorial wird nur Spring Data JPA verwendet.

Das zentrale Konzept zum Zugriff auf die mit JPA konfigurierte Datenbank sind die JPA Repositories. Dies sind Interfaces, die vom Interface JpaRepository<PersistentClass, KeyType> abgeleitet werden. Das Basisinterface JpaRepository wird dabei mit dem Klassentyp der persistenten Klasse (PersistentClass) und dem Typ des @ID-Attributs (KeyType) dieser Klasse parametrisiert. Spring Data generiert automatisch eine Implementierung für dieses Interface, die insgesamt 18 Methoden zur Verfügung stellt.

Es gibt mehrere Verfahren, weitere Methoden zu dem Interface hinzuzufügen und damit den generierten Funktionsumfang zu erweitern (Foliensatz). Die Spring Data JPA Referenzdokumentation ist hier recht ausführlich.

Beispiele für Named Queries und Native Queries

Spezielle Fälle

Einige Fälle sind in der Spring Dokumentation nicht besonders gut dokumentiert und auch in Foren nur schwer zu finden. Dazu gehört der Zugriff auf Subklassen aus dem Repository einer Superklasse. Mit einer nativen Query ist das ganz einfach und im Beispiel oben in Zeile 22 und 24 zu sehen.
Noch allgemeiner ist das ResultSet Mapping, das in diesen Posts von Thorben Janssen beschrieben ist.

Transaktionen

Spring Data Queries sind standardmäßig transaktional. Das reicht manchmal nicht, da mehrere Queries in eine Transaktion eingebettet werden müssen. Auch Zugriffe auf assoziierte Objekte müssen oft innerhalb einer Transaktion stattfinden, da Assoziationen standardmäßig „lazy“ implementiert werden. D.h., assoziierte Objekte werden erst aus der Datenbank geholt, wenn im Java-Code auf sie zugrgriffen wird. Daher gibt es die Möglichkeit, Methoden mit der Annotation @Transactional als transaktional zu markieren, um sie innerhalb einer Transaktion ablaufen zu lassen. @Transaktional kann auch eine ganze Klasse annotieren, das gilt dann für alle Methoden. Lang dauernde Aktionen, z.B. Benutzerinteraktionen, sollten innerhalb transaktionaler Methode unbedingt vermieden werden, um Blockierungen der Datenbank zu verhindern. Viele Services sind transaktionale Klassen, z.B. die Services, die die Benutzerschnittstelle mit dem zentralen Domain-Modell verbinden. Aber auch Testmethoden müssen häufig transaktional sein.

Beispiele

Aufgaben

  1. Schreiben Sie Repository Interfaces für Ihre eigenen Klassen, die Sie dem Projekt hinzugefügt haben.
  2. Ersetzen Sie die findAll().sort { ... }  Methodenaufrufe in Zeile 41 ff. in ProjectService.groovy durch eine sortierende Query.

Ein Gedanke zu „Spring Repositories“

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.