# Mehrere "selectOne" persistieren



## FINF_AW_Alex (4. Nov 2014)

Hallo zusammen !!

Ich arbeite gerade an meinem Projekt für die Fachinformatikerprüfung und hab ein kleines Problem.

Ich möchte eine Datenbankentity über mehrere selectOne Menüs zusammenbasteln.



Die selectOne Menüs erhalten ihre Daten bereits aus der Datenbank:


```
public List<MethodEntity> getMethods() {
  
         Query query = em.createQuery("SELECT data FROM MethodEntity data");
         
         List<MethodEntity> resultList = query.getResultList();
         
        return resultList;
    }    
    
    public List<GroupEntity> getGroups() {
  
         Query query = em.createQuery("SELECT data FROM GroupEntity data");
         
         List<GroupEntity> resultList = query.getResultList();
         
        return resultList;
    }
    
    public List<UserEntity> getUsers() {
  
         Query query = em.createQuery("SELECT data FROM UserEntity data");
         
         List<UserEntity> resultList = query.getResultList();
         
        return resultList;
```

Mein Problem ist jetzt das ich nicht ganz verstehe wie ich die selectierten Werte der einzelnen Menüs an eine Methode übergeben kann um diese dann zu persistieren.

hier noch der JSF Code, der Commandbutton hat noch keine Aktion weil ich ja genau da nicht weiss wie ich es angehen soll.


```
<h:form id="form_selectone">
           <h:panelGrid columns="4">
                <p:selectOneMenu id="selectone_methods" value="#{aclBean.methods}"
                                 style="margin-left: 5px;">
                    <f:selectItems value="#{aclBean.methods}" var="method"
                                   itemValue="#{method.method}" itemLabel="#{method.method}" />
                </p:selectOneMenu>            

                <p:selectOneMenu id="selectone_groups" value="#{aclBean.groups}"
                                 style="margin-left: 5px;">
                    <f:selectItems value="#{aclBean.groups}" var="group"
                                   itemValue="#{group.group1}" itemLabel="#{group.group1}" />
                </p:selectOneMenu>

                <p:selectOneMenu id="selectone_users" value="#{aclBean.users}"
                                 style="margin-left: 5px;">
                    <f:selectItems value="#{aclBean.users}" var="user"
                                   itemValue="#{user.userid}" itemLabel="#{user.username}" />
                </p:selectOneMenu>

               <p:commandButton value="create" style="margin-left: 5px;" /> 
           </h:panelGrid>
        </h:form>
```


Kann ich aus einer KLasse heraus darauf zugreifen oder kann ich per action-Attribut eine <List> mit den werten übergeben?

Tipps wären sehr hifreich ich hab irgendwie grad keine Idee :-(

Im Internet hab ich dazu leider nichts gefunden ich hoffe ihr könnt mir da weiterhelfen. 

Grüße Alex !!


----------



## FINF_AW_Alex (4. Nov 2014)

UPDATE:

Ich habe es versucht indem ich eine neue "AclEntity" mit den Eigenschaften(methode,gruppe,user) angelegt habe.
Die Eigenschaften habe ich mit jedem "value" - Attribut des zugehörigen "selectItems" - Tags verknüpft.

Für die speicherung habe ich eine storeAcl() - Methode geschrieben die dann die AclEntity auf Knopfdruck persistiert.

Leider passiert auf "Knopfdruck" rein garnichts.

ich bin ratlos 


JSF
------------------------

```
<h:form id="form_selectOne">
           <h:panelGrid columns="4">
                <p:selectOneMenu id="selectone_methods" value="#{aclBean.methods}"
                                 style="margin-left: 5px;">
                    <f:selectItems value="#{aclBean.methods}" var="method"
                                   itemValue="#{aclPM.entity4.methode}" itemLabel="#{method.method}" />
                </p:selectOneMenu>            

                <p:selectOneMenu id="selectone_groups" value="#{aclBean.groups}"
                                 style="margin-left: 5px;">
                    <f:selectItems value="#{aclBean.groups}" var="group"
                                   itemValue="#{aclPM.entity4.gruppe}" itemLabel="#{group.group1}" />
                </p:selectOneMenu>

                <p:selectOneMenu id="selectone_users" value="#{aclBean.users}"
                                 style="margin-left: 5px;">
                    <f:selectItems value="#{aclBean.users}" var="user"
                                   itemValue="#{aclPM.entity4.username}" itemLabel="#{user.username}" />
                </p:selectOneMenu>

               <p:commandButton value="create" action="#{aclPM.storeAcl()}" style="margin-left: 5px;"
                                update="form_selectOne"/>
           </h:panelGrid>
        </h:form>
```


```
private AclEntity    entity4 = new AclEntity();
```


```
public void storeAcl(){
        System.out.println("ACL: 'Stored' ");
        bean.addEntry(entity4);
    }
```


```
public void addEntry(AclEntity entity){
    System.out.println("ACL: 'Added' ");
    em.persist(entity);
    }
```


-----------------------------------

Die Methoden sind alle sauber verknüpft, ich habe auch darauf geachtet das der übergebene Datentyp bei dem Presentation Model stimmt.

Ich kann mir echt nur vorstellen das ich irgendwas in der View falsch zugewiesen habe.
Und warum der Button gar nicht reagiert ist mir ein Rätsel...

Grüße Alex =^.^=


----------



## stg (4. Nov 2014)

FINF_AW_Alex hat gesagt.:


> Ich möchte eine Datenbankentity über mehrere selectOne Menüs zusammenbasteln.



Bitte was?



FINF_AW_Alex hat gesagt.:


> Die selectOne Menüs erhalten ihre Daten bereits aus der Datenbank:
> 
> 
> ```
> ...


Erster Fehler: Niemals Logik in den getter-Methoden ausführen. Bei jedem Aufruf der get-Methode (das können durchaus mehrere pro Seitenaufruf sein!) erhälst du andere Objekte, das führt oft zu Problemen. Initialisiere deine Listen z.B. im Konstruktor oder einer PostConstruct-Methode.



> Mein Problem ist jetzt das ich nicht ganz verstehe wie ich die selectierten Werte der einzelnen Menüs an eine Methode übergeben kann um diese dann zu persistieren.


Gar nicht. Du musst die Werte keiner Methode übergeben, sondern du rufst einen Listener oder action-Methode auf, die dann direkt auf die Attribute in der zugrunde liegenden Bean zugreift.


----------



## FINF_AW_Alex (4. Nov 2014)

Hallo stg und Danke für die schnelle Antwort.



> Bitte was?



Also ich möchte gerne aus den DropDownMenüs (Foto oben) einen Tabelleneintrag mit eben den selektierten Werten erschaffen. Die Tabelle wurde jetzt schon als Entity erstellt (POST 2) und ich muss nur noch irgendwie die Daten reinschaufeln... ^^



> Gar nicht. Du musst die Werte keiner Methode übergeben, sondern du rufst einen Listener oder action-Methode auf, die dann direkt auf die Attribute in der zugrunde liegenden Bean zugreift.



Ja, das war auch meine erste Idee, in meinem 2ten Post habe ich das ja auch versucht. Doch ich bin mir eben nicht ganz sicher wie ich die "selektierten" Inhalte in einer Klasse und nicht in der View ansprechen kann... :bahnhof:



> Erster Fehler: Niemals Logik in den getter-Methoden ausführen.



Danke für den Hinweis. Das klingt logisch, ich bin allerdings ziemlich neu in Java und JavaEE erst recht. Ich hab mir den Aufbau an einem Beispiel von Jörn Hameister ( hier ) abgeschaut und hielt das für kompetent 

In welchen Konstruktor müsste ich das denn die QUERY einbetten?

Grüße Alex !!


----------



## stg (4. Nov 2014)

FINF_AW_Alex hat gesagt.:


> Doch ich bin mir eben nicht ganz sicher wie ich die "selektierten" Inhalte in einer Klasse und nicht in der View ansprechen kann...



...der Satz ergibt für mich null Sinn. Dir scheinen nicht nur JEE-, sondern auch ganz allgemein OOP-Grundlagen zu fehlen, fürchte ich. Dann wird das hier schwierig werden.


Wie auch immer. Schau dir noch einmal deine selectOneMenus an. Deine Verwendung von *itemValue* ist unsinnig. Hiermit ist der Wert gemeint, der hinter der jeweiligen Auswahloption im DropDown steht. Die Verwendung von *value* im selectOneMenu selbst ebenfalls, hierher gehört das Feld, in welchem du den Wert tatsächlich speichern willst. Ob du dort nun direkt in ein Feld vom jeweiligen Typ schreibst, oder in das entsprechende Feld vom einer Instanz von AclEntity ist relativ egal, wobei zweiteres sicherlich sinnvoller ist. (öffentliche getter/setter nicht vergessen!) 

Vermutlich musst du auch noch passende Converter schreiben, aber das wirst du dann später merken, wenn er meckert, dass er dir den Wert nicht gescheit zuweisen kann.

EDIT: 



FINF_AW_Alex hat gesagt.:


> In welchen Konstruktor müsste ich das denn die QUERY einbetten?



In der ManagedBean die hinter der View steht kannst du die Listen initialisieren. Bzw ganz allgemein in der Bean, welche die Listen bereitstellt 
Ich halte meine ManagedBeans selbst aber generell komplett frei von Datenbank-Kommunikation, sondern ich gehe dabei über einen extra Kontroller, welcher ein entsprechendes generisches Interfaces implementiert.


----------



## Joose (4. Nov 2014)

[ot]@stg: Bitte benutze die Möglichkeit deinen Beitrag zu editieren solange es möglich ist. Natürlich nur wenn dazwischen keine anderen Posts erfolgt sind [/ot]


----------



## FINF_AW_Alex (5. Nov 2014)

> ...der Satz ergibt für mich null Sinn.



Ja, für mich heute auch nicht mehr so viel. Das Problem war einfach das ich nicht wusste welcher *value* in der Komponente für was steht. Ich finde auch keine gescheite Doku für die Komponenten.



> Dir scheinen nicht nur JEE-, sondern auch ganz allgemein OOP-Grundlagen zu fehlen, fürchte ich.



Dir auch einen schönen Guten Morgen! Die Grundlage sind schon da. Doch zu meiner Verteidigung, ich hatte in meiner Ausbildung nur einen JAVA - Crashkurs von 8 Wochen und bin vorher noch nie mit OOP in berührung gekommen. JSF, PrimeFaces, JPA, EJB´s bringe ich mir gerade alles seit 4 Wochen selber im Praktikum über Bücher und Videos bei, manchmal weiss ich da nicht mehr wo oben und unten ist :-(

--------------------------------------------------
Zum eigentlichen Problem:

Danke mal für den Tipp :toll: !!

Ich habe den *value* des selectOneMenu geändert und jetzt wird auch in die Datanbank geschrieben.

Den *ItemValue* des selectItems habe ich dann mit dem selben Wert wie das Label gesetzt.



```
<p:selectOneMenu id="selectone_methods" value="#{aclPM.entity4.methode}"
                                 style="margin-left: 5px;">
                    <f:selectItems value="#{aclBean.methods}" var="method"
                                   itemValue="#{method.method}" itemLabel="#{method.method}" />
                </p:selectOneMenu>
```


Die View:
-------------




Die Datenbank:
--------------------



Ich weiss jetzt nicht was Du mit Convertern gemeint hast, die Daten sind doch alle vom Typ String.

Für mich sieht es jetzt so aus wie wenn alles ertmal funktioniert :-D

----------------------------

Zum Thema getrennte Inhalte:

Ich kann Dir da leider nicht ganz folgen und generisches Interface sacht mir eher nix ^^
Ich benutze ein Presentation Model auf das die View zugreift und das die Anfragen dann an die Bean weiterleitet. Es wird also bei mir auch nicht direkt aus der View auf die Bean zugegriffen.

Zumindest ist das der Plan  ja ich weiss klappt noch nicht ganz


----------



## stg (5. Nov 2014)

FINF_AW_Alex hat gesagt.:


> Ich weiss jetzt nicht was Du mit Convertern gemeint hast, die Daten sind doch alle vom Typ String.



Wenn das für dich ausreichend ist, dann gut... 
Ich war jedoch davon ausgegangen, dass du in deiner Entity `AclEntity` nicht nur Strings, sondern wirklich eine `Gruppe`, einen `User` und eine `Methode` speicherst. So hast du nun sowohl in der neuen Datenbanktabelle, als auch im Java Code keine Verbindung mehr zwischen den einzelnen Objekten. Wobei wir wieder bei Datenbank- bzw. OOP-Grundlagen wären. 
Das ganze ist ja auch kein Vorwurf, versteht das nicht falsch, es wird nur deutlich, dass dir noch Grundlagen fehlen. Sich in Technologien einzuarbeiten, welche darauf aufbauen, ist dann natürlich noch viel schwieriger.


----------



## FINF_AW_Alex (5. Nov 2014)

> Ich war jedoch davon ausgegangen, dass du in deiner Entity `AclEntity` nicht nur Strings, sondern wirklich eine `Gruppe`, einen `User` und eine `Methode` speicherst.



Das wäre ja auch schick, allerdings hab ich irgendwo gelesen das das nicht so einfach ist weil eine einfache datenbank nicht für objekte ausgelegt ist und man da nur BLOBS drin speichern kann.

Hast Du zu dem Thema vielleicht nen guten Link?



> Wobei wir wieder bei Datenbank- bzw. OOP-Grundlagen wären.



Ich glaube es gibt Grundlagen und "Grundlagen" ^^

Vielleicht habe ich nur die Grundlagen der Grundlagen aber im Mai mach ich meine Prüfung zum Fachinformatiker und wenn ich die bestehe muss ich ja irgendwas gelernt haben... ;-)

Ich werd mich wohl nochmal intensiver mit der JPA auseinandersetzen müssen aber in der Ausbildungszeit ist echt kaum Zeit für irgendwas... Und ich darf mir neben den ganzen Frameworks ja auch noch Netzwerke und BWL reinpfeifen.... :rtfm:

Grüße =^.^=


----------



## stg (5. Nov 2014)

FINF_AW_Alex hat gesagt.:


> Das wäre ja auch schick, allerdings hab ich irgendwo gelesen das das nicht so einfach ist weil eine einfache datenbank nicht für objekte ausgelegt ist und man da nur BLOBS drin speichern kann.
> Hast Du zu dem Thema vielleicht nen guten Link?



Du sollst in der Datenbank in der Tabelle ACL auch nicht jedes Mal die entsprechenden Gruppen-, User- und Methoden-Objekte speichern, sondern jeweils nur den passenden Key. DAS fällt wirklich aber wirklich unter Grundlagen, oder? Ohne ForeignKey-Constraints kann man sich den ganzen Spaß mir der Datenbank auch gleich schenken und einfach in Excel-Tabellen schreiben 
Die JPA löst dir dann jedenfalls die Relationen in beide Richtungen auf. Je nach Anforderungen kannst du in den Parent-Objekten eine Collection der Child-Objekte halten und/oder in den Child-Objekten eine Referenz auf das Parent-Objekt. Stichworte speziell hierzu sind `ManyToOne- und OneToMany-Annotationen`...


----------

