JSF JPA Glassfish - <ui:repeat

underzar

Mitglied
Hallo ich habe ein kleines Problemchen und sehe meinen Fehler nicht.
Könnt ihr mir bitte helfen, Danke;(???:L???:L???:L

Folgende Fehlermeldung wird ausgegeben

Code:
/admin/lieferanten.xhtml @10,19 value="#{lieferantController.findAll}": The class 'de.java.maven.glassfish.onlineshop.controller.LieferantController' does not have the property 'findAll'.

lieferanten.xhtml
Code:
<ui:composition template="/resources/templates/template.xhtml"
 xmlns="http://www.w3.org/1999/xhtml"
 xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
 xmlns:h="http://xmlns.jcp.org/jsf/html">
<ui:define name="content">

    
    <ui:repeat id="resulta" 
       value="#{lieferantController.findAll}" 
       var="list">
    <div>
        #{list.firma}
    </div>
</ui:repeat>
<h:panelGroup rendered="#{empty lieferantController.findAll}">
    list is empty!
</h:panelGroup>
</ui:define>
</ui:composition>

LieferantController.java
Code:
@Named
@RequestScoped
public class LieferantController implements Serializable {
    private static final long serialVersionUID = 1L;
	
    @PersistenceUnit
    private EntityManagerFactory emf;
	
    @Resource
    private UserTransaction ut;
    
    @Inject
    private Lieferant lieferant;    

    public Lieferant getLieferant() {
        return lieferant;
    }

    public void setLieferant(Lieferant lieferant) {
        this.lieferant = lieferant;
    }
       
    public List<Lieferant> findAll(){
        List<Lieferant> results = null;
        try {
            ut.begin();
            TypedQuery<Lieferant> query = 
                    emf.createEntityManager().createNamedQuery("Lieferant.findAll", Lieferant.class);
            results = query.getResultList();
        } catch (Exception e) {
            e.printStackTrace();
        }
       return results;
    }
    
    public String persist() {
		
	}

}

Lieferant.java
Code:
@Entity
@NamedQuery(name="Lieferant.findAll", 
            query="SELECT l FROM Lieferant l")
public class Lieferant implements Serializable {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private long id;
    
    private String firma;
    
    private String firmenZusatz;
    
    public Lieferant() {
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getFirma() {
        return firma;
    }

    public void setFirma(String firma) {
        this.firma = firma;
    }

    public String getFirmenZusatz() {
        return firmenZusatz;
    }

    public void setFirmenZusatz(String firmenZusatz) {
        this.firmenZusatz = firmenZusatz;
    }

    
    
}
 

stg

Top Contributor
Du bist hier aber im total falschen Unterforum gelandet... :)

Die Fehldermeldung ist doch eindeutig. Deine Bean hat kein Property >> findAll << (mit öffentlicher Standard-get-Methode). Auf dieses Property versucht du aber zuzugreifen: >> value="#{lieferantController.findAll}" << (sogar etwas später noch ein zweites Mal, aber das ist ja im Grund wurscht.

Was du machen solltest ist folgendes: Initialisiere deine Liste zu Beginn einmalig und speichere sie in einem private field in deiner Bean. Schreibe anschließend public getter/setter für dieses field und greife dann darauf zu.

In deinem konkreten Fall sollte es auch funktionieren, wenn du statt >> lieferantController.findAll << ganz einfach >> lieferantController.findAll() << schreibst. Aus vielerlei Gründen, die ich hier schon in anderen Themen zur Genüge heruntergeleiert habe, ist davon aber abzuraten. Daher hier einfach nur als Merkregel: Im JSF-Umfeld niemals Business-Logik in getter und setter Methoden schreiben!
 

Tente

Mitglied
Ich finds in deinen Antworten gerade nicht, warum man keine Geschäftslogik in getter und setter packen darf :(. Würde mich aber interessieren. Wir alle wollen ja möglichst sauberen Code schreiben.
 

stg

Top Contributor
Ich finds in deinen Antworten gerade nicht, warum man keine Geschäftslogik in getter und setter packen darf :(. Würde mich aber interessieren. Wir alle wollen ja möglichst sauberen Code schreiben.

Zum einen, weil die JavaBean Spec das ganz einfach vorschreibt... zum anderen, zum Beispiel, weil get-Methode während eines einzigen request durchaus mehrfach aufgerufen werden. Und zwar nicht nur, wenn sie mehrfach die View benutzt werden, sondern auch sonst ist das Verhalten ganz normal. Bei input-Componenten etwa während der Vaidation-Phase und anschließend nocheinmal während der Render-Response-Phase. Jetzt ist es natürlich äußerst blöd, wenn bei zwei aufeinanderfolgenden Aufrufen während eines Requests jeweils andere Ergebnisse zurückgeliefert werden, weil zwischenzeitlich anderweitig auf die Datenbank zugegriffen wurde...
Auch sollte es denke ich klar sein, dass es nicht die beste Lösung sein kann, wenn man zig mal die gleiche Datenbank-Abfrage auslöst, obwohl man jedesmal eigentlich das gleiche Ergebnis erwartet. Das verlangsamt den ganzen Prozess zudem ja auch enorm.
 
Zuletzt bearbeitet:

Tente

Mitglied
Verstehe. Klingt logisch. Allerdings muss man doch einen normalen Getter von einem Lazy-Getter unterscheiden, für die die Spec ganz verschieden sind. Und wenn man Lazy-Initialization verfolgt ist das meiner Meinung nach genau so legitim. Es gibt ganze Design-Pattern die darauf aufbauen... zB Factories.

Code:
private Typ typVar;

public Typ getIrgendwas(){
     if(this.typVar == null){
          this.typVar = anyFacade.loadIrgendwasFromDB();
     }

     return this.TypVar;

}

Findest du Lazy-Initialization/Getter sind im JSF Umfeld eher schlecht? Wenn ja, warum?
 

stg

Top Contributor
Nein, Lazy-Initialization ist im Grunde kein Problem. Man muss sich dann nur im Klaren darüber sein, was man da genau macht und den Überblick behalten / gescheit dokumentieren.

Bei gescheiter Wahl des Scopes seiner Beans und gleichzeitig gescheitem Lazy- bzw Eager-Loading seiner Daten direkt schon seitens JPA, benötigt man das aber in der Regel auch nicht wirklich.
 
Zuletzt bearbeitet:

Tente

Mitglied
Das sehe ich genau so. Intelligentes Prefetching und Caching von Informationen macht die ganze Angelegenheit wesentlich performanter. Ich glaube das was du ansprichst ist auch genau das, was immer wieder herausfordernd ist für einen JavaEE-Entwickler. Herauszufinden wie man möglichst effizient Daten zur Verfügung stellt ohne dabei jedoch alles zwischen zu speichern was man anfasst und ohne das man zu aufgeblähte Scopes verwendet. Wählt man aber den Scope zu klein kann es sein, dass man mehr Backend-Requests absetzen muss. Ein schmaler Grad.
 
Zuletzt bearbeitet:

Neue Themen


Oben