# JSF - c:foreach langsam



## megaflop (15. Dez 2010)

Hallo,

Ich habe gerade ein Problem mit c:foreach. Und nein, es geht nicht darum, dass es nicht macht was ich will.

Eingesetzt wird JavaEE 6, Glassfish 3.0.1, Mojarra 2.0.2. Ich habe mit dem Tag Performance-Probleme. Im einfachsten Fall würde das auf einer JSF-Facelets-Seite so aussehen:


```
<c:forEach var="foo" items="#{SomeEJB.all}">
            #{foo}<br/>
        </c:forEach>
```

Sagen wir, SomeEJB.getAll() führt irgendeine etwas länger laufende Datenbankabfrage durch. Umso mehr Ergebnisse getAll() hat, desto länger dauert der Seitenaufbau.

Ich habe mir das auch mit einem Profiler angeschaut. Ergebnis: getAll() wird so oft aufgerufen, wie es Ergebnisse gibt, und noch ein weiteres mal. Also bei 100 Ergebnissen 101 Mal pro Seitenaufruf. Wenn ich in dem Beispiel oben ui:repeat statt c:foreach benutze, wird getAll() genau ein Mal aufgerufen.

In meinem (etwas komplexeren  ) Fall kann ich nicht auf ui:repeat wechseln, weil ich darauf aufbaue, das eben der Inhalt der Schleife n-mal in den Komponentenbaum eingefügt wird, und nicht die Schleife selbst. Meine Frage also: Bug oder Feature? Gibt es einen anderen Work-around als ui:repeat? Gibts eine _Lösung_?

MfG,
Jonas


----------



## nocturne (20. Dez 2010)

Kein Wunder dass du Performanceprobleme hast.

Was wird in der Bean gemacht? Auf den Ersten Blick handelt es sich um ein View- und Modeling-aufgabe, nicht um eine Controlling-Aufgabe.

Wenn du wirklich das Controlling des MVC-Modells dafür nicht benötigst würde ich dein SQL-Statement aus dem Controller raushalten.
Das übliche Vorgehen gibt Oracle musterhaft vor:
How To Use Sql JSp Standard Library


----------



## megaflop (20. Dez 2010)

Danke schonmal für deinen Beitrag.

Die Objekte (foo) werden von einer EJB aus meiner Datenbank geholt. Dazu benutze ich JPA. Zwischen der EJB und dem Facelet hängt natürlich noch eine ManagedBean, die die Logik der JSF-Seite enthält (Navigationsmethoden, Properties für Eingabefelder, benötigte Methoden um die Ansicht aufzubauen, ...). Da ich auf der JSF-Seite eine Liste von foo verarbeiten will, enthält sie eben auch eine Methode, um alle Objekte foo zu erhalten. Diese Methode greift auf die EJB zu.

Das ändert aber am Problem nichts, deswegen habe ich es vereinfacht dargestellt.


----------



## DerEisteeTrinker (20. Dez 2010)

Sprich das c:foreach hat kein Performance-Problem, sondern der Datenbank-Zugriff und da hilft auch ein anderes JSP-Tag nicht. Überdenke die Anordnung der Aufrufe. Vllt kannst du Teile der Seite cachen bzw. in Listen vorhalten. Sollte das nicht gehen, dann überprüfe, ob nicht zu viele Daten selektiert werden und ob die Indizes richtig gewählt sind für die Anfrage


----------



## nocturne (21. Dez 2010)

Ok. Im EJB-Umfeld ist das natürlich auch etwas anderes, da sehe ich einen gewissen Kommunikationsaufwand.
Ich denke wir kommen dem Problem auf die Schliche.

1. Kannst du ein Datensatzlimit (SQL: LIMIT) an die EJB übergeben? Ich denke an eine art Datensatz-Walker.
2. Ein anderer Ansatz wäre für "NUR die Darstellung" die EJB mit einer direkten JDBC-Verbindung zu umgehen.

Uns würde für den ersten Fall ein Teil des Sourcecodes helfen.


----------

