JPA 2.0 Criteria API How To – GroupBy and Having

CriteriaQuery-Objekte bieten eine Möglichkeit mit dem JPA 2.0 Standard in Java typsichere Abfragen auf relationale Datenbestände unabhängig vom konkreten O/R-Mapping-Mechanismus zu spezifizieren. Über die groupBy() Methode des CriteriaQuery Interfaces lässt sich die Ergebnismenge gruppieren. Analog kann anhand der having() Methode über die Menge gefiltert werden.
Zur Verdeutlichung nutzen wir als Beispiels die bekannte Entitätsklasse Person.
Folgende JPQL-Abfrage selektiert alle Personen und gruppiert die nach dem Alter:

select p from Person p group by p.age

Die gleiche Abfrage lässt sich durch die Criteria-API bauen, indem das Beispiel für die Selektion angepasst wird und vor dem Absetzen des Queries die groupBy() Methode aufgerufen wird:

EntityManager em = entityManagerFactory.createEntityManager();
		CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
		CriteriaQuery criteriaQuery = criteriaBuilder.createTupleQuery();
		Root person = criteriaQuery.from(Person.class);
		criteriaQuery.groupBy(person.get(Person_.age));

Bei der Benutzung der groupBy() Methode muss jeder Selektionswert, der nicht das Ergebnis eine Aggregat Methode ist , eine “path expression” die für die Gruppierung benutzt wird, sein.

Das so gruppierte Ergebnis lässt sich nun noch einschränken/filtern. Es werden nur die Personen, die 20 oder 65 Jahre alt sind, abgefragt.

criteriaQuery.having(criteriaBuilder.in(person.get(Person_.age)).value(20).value(65));

Dies würde in JPQL folgendem Statement entsprechen:

select p.age, count(*) from Person p group by p.age having p.age in (20, 65) ;
Short URL for this post: http://wp.me/p4nxik-1Cv
This entry was posted in Java Persistence and tagged , , , , , . Bookmark the permalink.

Leave a Reply