Das JPA-Criteria API ermöglicht eine standardisierte und typsichere Erstellung von objektorientierten Abfragen in Java. Im folgenden soll die Umsetzung einer Join-Abfrage mit Hilfe der Criteria API etwas näher erläutert werden. Ausgangspunkt ist ein Beispiel einer
select p from Person p join p.adresses
Um die gleiche Join-Query durch das Criteria-API zu formulieren, ist folgende Objekthierarchie zu benutzen. Ein CriteriaQuery-Objekt liefert über die from()-Methode ein From-Interface-Objekt zurück. An diesem kann über die join()-Methode ein entsprechendes Join-Objekt erhalten werden. Als Parameter ist der join()-Methode ein Metamodel-Objekt zu übergeben, welches das Element der abgefragten Klasse beischreibt über die der spätere „Join“ erfolgen soll. Das erzeugte Join-Objekt nimmt sowohl das Quell- als auch das Ziel-Objekt des kartesischen Produkts auf. Zum Ausführen der Query ist dann das From-Interface-Objekt als Parameter der select()-Methode des entsprechenden CriteriaQuery-Objektes zu übergeben. Im Anschluss kann diese Query dann durch einen JPA-Entity-Manager ausgeführt werden. Die so implementierte Abfrage entspricht in JPQL: Die Join Objekte können dabei vom Typ Join, CollectionJoin, SetJoin, ListJoin und MapJoin sein. Der konkrete Typ des jeweils zurückgegebenen Join-Objektes wird vom Typ der Relation bestimmt. Um diese Filterung typsicher durchzuführen, ist das Ausgangsbeispiel wie folgt zu erweitern. Das Join-Objekt wird als Referenz gespeichert und kann so als Parameter zur Erzeugung eines Filter-Objektes in der where()-Methode des CriteriaQuery-Objektes genutzt werden. Der Parameter wird mit Hilfe von Operatoren-Methoden [wie z.B. equal()] des Criteriabuilders gebildet. Dazu kann über die gespeicherte Referenz auf dem Join-Objekt navigiert werden. Man beachte auch hier wieder die Verwendung von Metamodel Objekten der Klasse Person_ um die in der where-Klausel nötige Navigation zu spezifizieren.
EntityManager em = entityManagerFactory.createEntityManager();
CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
CriteriaQuery<person> criteriaQuery = criteriaBuilder.createQuery(Person.class);
Root<person> person = criteriaQuery.from(Person.class);
SetJoin<person, Address> adressJoin = person.join(Person_.adresses);
criteriaQuery.select(person);
List<person> resultList = em.createQuery(criteriaQuery).getResultList();
Auf das Join-Objekt kann zugegriffen werden, wenn Attribute des Zielobjektes in einer „select“ oder „where“- Klausel benötigt werden.
EntityManager em = entityManagerFactory.createEntityManager();
CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
CriteriaQuery<person> criteriaQuery = criteriaBuilder.createQuery(Person.class);
Root<person> person = criteriaQuery.from(Person.class);
SetJoin<person, Address> adressJoin = person.join(Person_.adresses);
criteriaQuery.where(criteriaBuilder.like(adressJoin.get(Address_.city), "Mannheim"));
criteriaQuery.select(person);
List<person> resultList = em.createQuery(criteriaQuery).getResultList();
select p from Person p join p.adresses a where a.city like 'Mannheim'
Für einen Join über eine Entität, ein Embeddable oder einen Basis Typen ist das Ergebnisobjekt selbst vom Basistyp Join.
Bei einem Join über eine Collection, die mit java.util.Collecion spezifiziert ist, ist das Ergebnis vom Typ CollectionJoin.
SetJoin ist das Ergebnis eines Join über eine Collection vom Typ java.util.Set. MapJoin hingegen ist das Ergebnis eines Join über eine Collection vom Typ java.util.Map.
Auf einem Join lassen sich im Anschluss mit Hilfe einer where-Klausel Filterungen durchführen wie folgendes Beispiel zeigen soll, das man in JPQL wie folgt formulieren würde:
select p from Person p join p.adresses a where a.street = 'Weinheimer str.'
EntityManager em = entityManagerFactory.createEntityManager();
CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
CriteriaQuery<person> criteriaQuery = criteriaBuilder.createQuery(Person.class);
Root<person> person = criteriaQuery.from(Person.class);
SetJoin<person, Address> a = person.join(Person_.adresses);
criteriaQuery.select(person).where(criteriaBuilder.equal(a.get(Address_.street), "Weinheimer str."));
criteriaQuery.select(person);
List<person> resultList = em.createQuery(criteriaQuery).getResultList();
-
Trivadis Developer Blog
This is the publication playground for these guys from OIO Trivadis, the Trivadis Group`s Java experts.
Tag cloud
Agile Methods and development Atlassian Tools Build, config and deploy Did you know? Eclipse Universe Groovy and Grails Java and Quality Java Basics Java EE Java modularization Java Persistence Java Runtimes - VM, Appserver & Cloud Java Web Frameworks MDSD Open Source BI Other languages for the Java VM Politics Security SOA / Webservices Spring Universe Web as a Platform XML Universe
Pingback: JPA 2.0 Criteria API How To – OrderBy | techscouting through the java news
Pingback: JPA 2.0 Criteria API How To – Join Type und Fetch Join | techscouting through the java news
Pingback: JPA 2.0 Criteria API How To – Join Type und Fetch Join | techscouting through the java news
Danke für das Tutorial. Von wo kommt die Variable Person_?
Hallo Peter,
ich habe in folgedem Artikel (http://blog.oio.de/2010/10/29/jpa-2-0-criteria-api-how-to/#metamodel) beschrieben, wie man sich Metamodel Klassen (Person_) generieren lassen kann. Ich hoffe, das hilft Dir weiter, sonst einfach nochmal melden.