Start - Projekte - Wissen - Impressum -
Prozesse & Systeme - Optimierung von Entwicklungsprozessen

Paging mit setFirstResult und setMaxResults


Paging ist eine Optimierung, bei der über große ResultSets seitenweise navigiert wird. JPA unterstützt Paging, dabei können Queries mit den entsprechenden Angaben versehen werden:

Query query = em.createNamedQuery("Person.findByName");
query.setParameter("name", personName);
query.setFirstResult(50 * page);
query.setMaxResults(50);
// das Resultat wird nur max. 50 Einträge haben:
List<Person> persons = query.getResultList();
Die entsprechenden Paging-Informationen werden datenbankspezifisch an das Select angehängt und datenbankseitig ausgeführt.

Im Zusammenhang mit der Lösung des N+1 Problems für @OneToMany Relationen gibt es einen wichtigen Seiteneffekt zu berücksichtigen. Angenommen man findet im skizzierten Beispiel 10 Entitäten Person mit jeweils 10 Entitäten Organisation. Dann wird ein JOIN FETCH ein Ergebnis mit 100 Einträgen liefern, die 10 Personen jeweils redundant für die 10 Organisationen! Die Angaben zum Paging lassen sich aber nicht ohne weiteres auf dieses Resultat projizieren und die JPA Spezifikation stellt klar:

The effect of applying setMaxResults or setFirstResult to a query involving 
fetch joins over collections is undefined. (JPA "Enterprise JavaBeans 3.0, 
Final Release", Kapitel 3.6.1 Query Interface)
Hibernate liefert das richtige Ergebnis, indem es bei Join Fetches das Paging im Hauptspeicher der Anwendung durchführt. Auf das damit verbundene konzeptionelle Problem (dass ein Teil der Query von der JVM statt von der Datenbank ausgeführt wird) weist Hibernate hin:
WARNUNG: firstResult/maxResults specified with collection fetch; applying in memory!
Man vermeidet am besten die Kombination der Join Fetch Strategie mit Paging.

copyright © 2002-2012 | Dr. Christian Dürr | prozesse-und-systeme.de | all rights reserved