© DrHitch/Shutterstock.com
JPA 2.1

2 Queries


Es gibt zwei Query-Bereiche, aus denen die neuen JPA-2.1-Features kommen:

  • JPQL (Java Persistence Query Language)
  • Criteria API

Das Hauptkapitel „Queries“ wurde daher in zwei Unterkapitel unterteilt.

2.1 JPQL

2.1.1 Polymorphie in Queries

Downcasting

Analog zu Typecasts in Java können auch in JPQL-Queries Typwandlungen durchgeführt werden, um so auf Eigenschaften abgeleiteter Entity-Klassen zugreifen zu können.

Das Problem in JPA 2.0

Queries sind per Default polymorph, d. h. es werden auch Objekte abgeleiteter Klassen einbezogen. Sind also bspw. die Entity-Klassen Vehicle und Car voneinander abgeleitet, so liefert die Query select v from Vehicle v auch Car-Objekte, wenn diese in der Datenbank vorhanden sind. Bis JPA 2.0 gibt es allerdings keine Möglichkeit, den Typ der selektierten Objekte in Bedingungen zu nutzen oder auf Attribute abgeleiteter Klassen zuzugreifen.

Die Lösung in JPA 2.1

Mithilfe der neuen Query-Funktion type(x) kann der Typ der selektierten Objekte erfragt und bspw. zur Einschränkung der Ergebnismenge verwendet werden (Listing 2.1).

// Selektion von Objekten mit dem exakten Typ Car
em.createQuery("select v from Car v where type(v)=Car",
Car.class) …

Listing 2.1: Einschränkung des Selektionsergebnisses anhand des Typs

Seit JPA 2.1 ist es darüber hinaus möglich, mithilfe der Funktion treat(x as T) auf Eigenschaften abgeleiteter Klassen zuzugreifen. Treat stellt einen sog. Downcast auf den angegebenen Typ dar (Listing 2.2).

// Selektion von Name und Anzahl von Türen (Car-Attribut!)
select v.name, treat(v as Car).noOfDoors from Vehicle v

// Selektion abhängig von Subclass-Eigenschaften
select v from Vehicle v
where treat(v as Lorry).payLoad>30
or treat(v as Ship).tonnage>130000

Listing 2.2: Downcast von Query-Variablen

Treat hat neben der Downcast-Funktionalität auch eine Filterwirkung, d. h. Objekte mit falschem Typ sind nicht Teil der Ergebnismenge. Im ersten Beispiel-Select sind somit nur Car-Objekte im Ergebnis, im zweiten Select analog nur Objekte der Typen Lorry und Ship.

2.1.2 Dynamische Queries

Dynamically defined Named Queries

Ermöglichen das dynamische Hinzufügen von Named Queries zur Laufzeit der Anwendung. Queries sind somit konfigurierbar und können zur Laufzeit geladen werden.

Das Problem in JPA 2.0

Es gibt zwei Möglichkeiten, JPQL-Queries an den Entity Manager zu übergeben: Zum einen können die Queries direkt als String und zum anderen indirekt über den Namen der Query selbst übergeben werden. Wir sprechen dann von Named Queries (Listing 2.3).

// Direkt als String 
TypedQuery<Country> query =
em.createNamedQuery("select c from Country c where c.phonePrefix=:phonePrefix", Country.class);

// Indirekt über den Namen der Annotation
TypedQuery<Country> query =
em.createNamedQuery("Country_findByPhonePrefix", Country.class);

Listing 2.3: Unterschied zwischen direkter und indirekter Query-Definition

Named Queries werden über die Annotation @NamedQ...

Neugierig geworden? Wir haben diese Angebote für dich:

Angebote für Gewinner-Teams

Wir bieten Lizenz-Lösungen für Teams jeder Größe: Finden Sie heraus, welche Lösung am besten zu Ihnen passt.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang