Criteria Queries in JPA 2.0

JPA 2.0 bietet als eine der groß angekündigten Neuerungen sog. Criteria Queries an. Damit ist es möglich, Queries in objektorientierter Weise zusammenzusetzen und dabei die Vollständigkeit und die Typkorrektheit weitgehend zu garantieren.

Eine herkömmliche Query sähe bsw. so aus:

TypedQuery q = em.createQuery(„select e from SomeEntity e where e.name=’Hugo'“, SomeEntity.class);

Das ist zwar relativ einfach und überschaubar, birgt aber ein paar Stolperfallen:
– Ist die Query formal vollständig?
– Passen die selektierten Werte zum Typ der Query?
– Heißt das Attribut wirklich name?
– Hat das verglichene Attribut wirklich den Typ String?

Nichts davon kann zur Compilezeit geprüft werden, da dazu der JPQL-Text geparst werden muss. Das hier eingesetzte, neue, getypte Interface TypedQuery hilft hier auch nicht weiter; seine Vorteile liegen erst in der hier nicht gezeigten weiteren Verarbeitung der Query.

Als Criteria Query sähe das Beispiel so aus:

CriteriaBuilder builder = em.getCriteriaBuilder();

// Criteria Query für Ergebnistyp erzeugen
CriteriaQuery cQuery = builder.createQuery(SomeEntity.class);

// Projektionsvariablen erzeugen (FROM-Klausel)
Root c = cQuery.from(SomeEntity.class);

// Selektion angeben (SELECT-Klausel)
cQuery.select(c);

// Bedingung erstellen und der Query hinzufügen
Path cName = c.get(SomeEntity_.name);
Predicate hatNamen = builder.equal(cName, builder.parameter(String.class, „name“));
cQuery.where(hatNamen);

// Normale Query erstellen
TypedQuery q = em.createQuery(cQuery);

Was hat’s nun gebracht?

Zunächst kann man durch die geschickte Verflechtung der zu nutzenden Typen kaum etwas vergessen, die Query wird also formal vollständig sein. Man könnte im Beispiel höchstens die SELECT-Klausel vergessen, was zur Compilezeit deshalb nicht geprüft werden kann, da eine Query ja nicht in jedem Fall etwas selektiert.

Im Falle der SELECT-Klausel sieht man aber bereits einen Vorteil: Versucht man hier etwas zu selektieren, was nicht zum Typ der Query passt, ist ein Compile-Fehler die Folge.

Beim Aufbau der WHERE-Bedingung, genauer des darin genutzten Prädikats, werden zwei weitere Vorteile deutlich: Zum einen wird durch die Verwendung des statischen Metamodells – hier in Form der Klasse SomeEntity_ – sicher gestellt, dass das verwendete Attribut der Entity existiert. Zum anderen wird auch hier Typsicherheit erreicht, ebenfalls durch das Metamodell, das für das Attribut name den Typ String „kennt“.

Die Criteria Query erzeugt also zwar einen höheren Schreibaufwand als die herkömmliche Query, bietet dem Entwickler aber eine deutlich höhere Sicherheit, korrekten Code geschrieben zu haben.

Das gezeigte Beispiel setzt allerdings voraus, dass zu jeder Entity-Klasse E eine statische Metamodell-Klasse E_ existiert, die die Metadaten der persistenten Attribute von E enthält. Das statische Metamodel kann man theoretisch manuell erstellen, sinnvoll ist aber m.E. nur die automatische Generierung. Die gelingt durch Annotations-Prozessoren, die seit Java 6 wie Plugins in den Compilerlauf eingeschoben werden können. So kann man bspw. den Hibernate Static Metamodel Generator verwenden. Dies funktioniert auch, wenn nicht Hibernate als JPA-Provider genutzt werden soll, da das Metamodell Provider-übergreifend spezifiziert ist.

Der Einsatz des Hibernate Static Metamodel Generator ist auf der folgende Webseite recht gut erläutert:
http://relation.to/Bloggers/HibernateStaticMetamodelGeneratorAnnotationP…

Advertisements

Über Dirk Weil
Dirk Weil ist seit 1998 als Berater im Bereich Java tätig. Als Geschäftsführer der GEDOPLAN GmbH in Bielefeld ist er für die Konzeption und Realisierung von Informationssystemen auf Basis von Java EE verantwortlich. Seine langjährige Erfahrung in der Entwicklung anspruchsvoller Unternehmenslösungen machen ihn zu einem kompetenten Ansprechpartner und anerkannten Experten auf dem Gebiet Java EE. Er ist Autor in Fachmagazinen, hält Vorträge und leitet Seminare und Workshops aus einem eigenen Java-Curriculum.

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

%d Bloggern gefällt das: