JPA 2.0 Criteria API – Join How To

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.

		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();

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.
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();

Die so implementierte Abfrage entspricht in JPQL:

select p from Person p join p.adresses a where a.city like 'Mannheim'

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.
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.'

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.

		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();

Man beachte auch hier wieder die Verwendung von Metamodel Objekten der Klasse Person_ um die in der where-Klausel nötige Navigation zu spezifizieren.

Short URL for this post: http://wp.me/p4nxik-11O
This entry was posted in Java EE, Java Persistence and tagged , , . Bookmark the permalink.

5 Responses to JPA 2.0 Criteria API – Join How To

  1. Pingback: JPA 2.0 Criteria API How To – OrderBy | techscouting through the java news

  2. Pingback: JPA 2.0 Criteria API How To – Join Type und Fetch Join | techscouting through the java news

  3. Pingback: JPA 2.0 Criteria API How To – Join Type und Fetch Join | techscouting through the java news

  4. Peter Müller says:

    Danke für das Tutorial. Von wo kommt die Variable Person_?

Leave a Reply