Datenbankabfragen mit JPA – mehr als nur em.find und JPQL

Seite 3: Stored Procedures

Inhaltsverzeichnis

Zusätzlich zu den klassischen Abfragen bietet JPA seit der Version 2.1 eine direkte Unterstützung für den Aufruf von Stored Procedures. In der Vergangenheit ließen sie sich nur mithilfe einer nativen SQL-Abfrage ausführen. Mittlerweile unterstützt JPA mit der createStoredProcedureQuery des EntityManager und der @NamedStoredProcedureQuery-Annotation auch die Möglichkeit, Stored Procedures direkt auszuführen. Ähnlich zu JPQL- und nativen SQL-Abfragen erfolgt hier die Unterscheidung in ad hoc und bereits zum Deployment-Zeitpunkt vorbereitete, per Annotation definierte Aufrufe.

Das nachfolgende Codebeispiel zeigt den Aufruf der Stored Procedure sum mit zwei Eingabe- und einem Ausgabeparameter.

StoredProcedureQuery query = em.createStoredProcedureQuery("sum");
query.registerStoredProcedureParameter("a", Double.class, ParameterMode.IN);
query.registerStoredProcedureParameter("b", Double.class, ParameterMode.IN);
query.registerStoredProcedureParameter("sum", Double.class,
ParameterMode.OUT);

query.setParameter("a", 5.67d);
query.setParameter("b", 1.33d);

query.execute();

Zu Beginn wird die createStoredProcedureQuery-Methode des EntityManager mit dem Namen der auszuführenden Stored Procedure aufgerufen, um eine neue Instanz einer StoredProcedureQuery zu erzeugen. Diese repräsentiert den auszuführenden Aufruf und wird anschließend verwendet, um die Ein- und Ausgabeparameter zu definieren. In diesem Fall erwartet die Stored Procedure zwei Eingabeparameter mit den Namen a und b und liefert den Rückgabewert sum zurück.

Nachdem die Definition des Stored-Procedure-Aufrufs abgeschlossen ist, werden die Werte der Eingabeparameter übergeben und die Stored Procedure ausgeführt. Die Definition und Verwendung einer @NamedStoredProcedureQuery folgt demselben Prinzip. Allerdings wird hierbei die auszuführende StoredProcedureQuery per Annotation bestimmt.

@Entity
@NamedStoredProcedureQuery(
name = "sum",
procedureName = "sum",
parameters = {
@StoredProcedureParameter(mode = ParameterMode.IN, type =
Double.class, name = "a"),
@StoredProcedureParameter(mode = ParameterMode.IN, type =
Double.class, name = "b"),
@StoredProcedureParameter(mode = ParameterMode.OUT, type =
Double.class, name = "sum") })
public class Author { ... }

Der Name der so definierten @NamedStoredProcedureQuery lässt sich anschließend an die createNamedStoredProcedureQuery-Methode des EntityManager übergeben, um eine StoredProcedureQuery-Instanz zu erzeugen. Wie im vorherigen Beispiel wird die StoredProcedureQuery anschließend verwendet, um die Werte der Eingabeparameter zu setzen und die Stored Procedure aufzurufen.

StoredProcedureQuery query = em.createNamedStoredProcedureQuery("sum");

query.setParameter("a", 5.67d);
query.setParameter("y", 1.33d);

query.execute();

Stored Procedures werden nur selten in Java-Anwendungen verwendet, da die meisten Entwickler möglichst wenig Logik in die Datenbank auslagern möchten. Für besonders datenintensive Operationen kann das aber sinnvoll sein, da die Datenbank diese besonders effizient ausführen kann und somit eine bessere Performanz ermöglicht. Daher empfiehlt es sich in solchen Fällen, mit einem Datenbankadministrator über den Einsatz einer Stored Procedure zu diskutieren und diese gegebenenfalls per StoredProcedureQuery oder @NamedStoredProcedureQuery aufzurufen.