# JSF selectOneMenu



## ModellbahnerTT (24. Aug 2009)

Hallo,

ich habe ein selectOneMenu mit welchem Personen ausgewählt werden sollen.
Die Personen habe ich bereits in ein SelectItem gepackt und sie werden erfolgreich in der Liste angezeigt.

Jetzt will ich aber mit der selektierten Person weiterarbeiten und genau das funktioniert nicht. Apache Tomcat schreibt:
"detail=(Konvertierungs-Fehler: Wert 'Vorname Nachname' für Modell 'null Converter' : Ausnahme: {2}.)

[JAVA=20]
<h:form>
    <h:selectOneMenu value="#{personController.person}">
        <f:selectItems value="#{personController.personen}" />
    </h:selectOneMenu>
    <h:commandButton action="showPerson" value="Anzeigen" />
</h:form>
[/code]


```
public class PersonController {
    Person p;
    
    public Person getPerson() {
        if(p==null)
            p = new Person();
        return p;
    }

    public void setPerson(Person p) {
        this.p = p;
    }

    public SelectItem[] getPersonen() {
        return new SelectItem[] {new SelectItem(new Person("Vorname", "Nachname" ....
    }
}
```

Danke


----------



## Rydl (29. Aug 2009)

es scheint, du verwendest keinen converter.
versuch doch lieber einen String, Integer oder ähnliches statt eines "Person" objekts in das selectItem zu übergeben, wenn du keinen converter hast.

statt

```
<h:selectOneMenu value="#{personController.person}">
```
lieber

```
<h:selectOneMenu value="#{personController.personId}">
```

und dann in deiner backing bean entsprechende konvertierlogik von personId zu person...


----------



## Prismapanda (30. Aug 2009)

Die "Konvertierungslogik" gehört IMHO unbedingt in den Converter und so ein Converter ist ja schnell geschrieben, also solltest du das auch tun.


----------



## ModellbahnerTT (30. Aug 2009)

ah, danke
hab das schon mal wo gelsesen, dass man einen Converter braucht, dachte aber das es auch einfacher gehen muss (schade eigentlich)

könnte mir jemand erklären wie man so einen converter schreibt?
die Klasse Person ist eh nur ein einfaches POJO mit vorname, nachname, geburtsdatum usw..

ich hab schon ziemlich lang gegoogelt, aber finde zu dem thema echt gar nix bzw kann damit nicht sehr viel anfangen...

Danke


----------



## Rydl (30. Aug 2009)

du findest dazu nichts? ich geb dir mal ein paar keywords für google: jsf converter example
wenn du das eintippst, findest du allerhand, als erstes kommt bei mir folgende seite mit gutem beispiel: Custom Converter Example


----------



## ModellbahnerTT (1. Sep 2009)

ja diese seite hab ich auch schon gefunden, aber ich kann damit überhaupt nichts anfangen. Ich habe ein Person Objekt, wo in der Liste nur die Nachnamen angezeigt werden. Woher soll ich die anderen Werte hernehmen um das Objekt konvertieren zu können?

Ich finde keine Beispiele die in die Richtung von meinem gehen. Nur Datum oder Zeitkonvertierung usw. Aber keine größeren Objekte ...


----------



## Rydl (2. Sep 2009)

wo du die hernehmen sollst? na wo bekommst du die werte denn sonst her? aus der datenbank direkt oder aus einem cache. 
entitäten haben ja meist einen primärschlüssel, eine id, die sich leicht als value hinter dem label eines selectItems verstecken kann. wenn du deine datenbank nach der ausgewählten id fragst, wird sie dir sicher das richtige objekt geben =D


----------



## ModellbahnerTT (2. Sep 2009)

genau... aber das problem ist, ich verwende RichFaces und dabei wird das Label eines selectItems nicht berücksichtigt


----------



## Rydl (2. Sep 2009)

in deinem beispiel konnte ich nichts richfaces-spezifisches erkennen und auch sonst sollte es egal sein, dass du zusätzlich noch richfaces verwendest. rf basiert ja auch nur auf jsf, label und value werden dort genauso "berücksichtigt", wie bei jsf ohne alles 
befolge doch einfach noch mal die beispiele aus dem internet genau und wenn du dann noch probleme hast, poste doch etwas neuen code und ggf. noch fehlermeldungen.

12.6 Creating Custom JSF Converters
JSF Converter and h:selectOneMenu (JSF forum at JavaRanch)
Add your own converter in RichFaces  Julien Colin

viel glück


----------



## piwo (4. Sep 2009)

Hi,

du hast eigentlich 2 Probleme

1. ein SelectItem hat ein Label und ein Value. Label ist das was du angezeigt bekommst, z.Bsp. in einer ListBox. Der Value ist dar Wert ("ID") welcher den Label referenziert.
Stell dir am besten ein Html-Select-Option vor: <option value="ID">Label</option>
Nichts anderes repräsentiert ein SelectItem.

2. Du hast das Prinzip von Convertern noch nicht richtig verstanden, speziell Converter für Klassen/Beans.
Ein Converter besitzt 2 grundlegende Methoden: getAsObject und getAsString
getAsString wird verwendet um eine ID aus einem Objekt zu bekommen
getAsObject funktioniert genau anders herum. Diese Methode nimmt eine ID entgegen und gibt dir das Objekt dazu zurück

Ich habe für solche Fälle folgendes verwendet:
Ich erstelle mir ein SelectItem und definiere als Label das was ich angezeigt bekommen möchte, z.Bsp. den Namen einer Person. Als Value gebe ich das Objekt Person mit.
Dazu habe ich mir einen Converter für die Klasse Person definiert. getAsString nimmt jetzt das Personen-Objekt und gibt mir die Id als String zurück.
Die getAsObject-Methode bekommt nun wieder die Id. Mit dieser Id mache ich eine Datenbankabfrage und hole mir das Objekt aus der Datenbank, welches über die Id referenziert wird. Dieses Objekt gebe ich dann zurück.

Das JSF Framework kümmert sich nun um die Konvertierung. Da brauchst du nichts weiter einstellen, außer den Converter richtig in die faces-config.xml schreiben.

Noch ein Tipp zum Schluss: vergesse die Seite JSP Tutorials,EJB Tutorial,JDBC Tutorials,Free Java Servlets Tutorials, WAP Tutorials, Spring Framework Tutorials, J2EE Tutorials, BioInformatics Tutorials, Java Server Faces Tutorials, Jboss Tutorials, Hibernate Tutorials, XML and MySQL Tutorials! Sie enthält viele Fehler die im Detail stecken, die einem aber leider erst später bewusst werden, wenn man tiefer in die Materie eingedrungen ist ;-)


----------



## ModellbahnerTT (20. Sep 2009)

habe das jetzt genau so gemacht, aber es kommt folgende exception:

sourceId=personFormerson[severity=(ERROR 2), summary=(personForm:land: Validierungs-Fehler: Wert nichg göltig.), detail=(personForm:land: Validierungs-Fehler: Wert nichg göltig.)]

wenn ich in der getAsObject methode immer null zurück gebe, kommt diese Exception nicht.


----------



## ModellbahnerTT (20. Sep 2009)

habe gerade gelesen, dass das Objekt, dass konvertiert werden soll, eine equals Methode benötigt. Habe diese eingefügt, aber es kommt noch immer der gleiche Fehler.


----------



## piwo (21. Sep 2009)

Hi,

füge auch nochmal die Methode 
	
	
	
	





```
hashCode()
```
 deiner Person-Klasse hinzu. Dies sollte allerdings noch nicht die Lösung sein.
Hilfreich wäre es jetzt nochmal die gesamt Person-Klasse, sowie der Formular zu sehen....


----------



## damien (21. Sep 2009)

ModellbahnerTT hat gesagt.:


> habe das jetzt genau so gemacht, aber es kommt folgende exception:
> 
> sourceId=personFormerson[severity=(ERROR 2), summary=(personForm:land: Validierungs-Fehler: Wert nichg göltig.), detail=(personForm:land: Validierungs-Fehler: Wert nichg göltig.)]
> 
> wenn ich in der getAsObject methode immer null zurück gebe, kommt diese Exception nicht.



Kann es sein, dass das Objekt, das du aus der Datenbank holst nicht mit deinen JPA/JSF-"Constraints" konform geht ?


----------



## ModellbahnerTT (21. Sep 2009)

@piwo: kann die klassen momentan nicht posten, da ich an einem anderen PC arbeite! hashCode habe ich natürlich auch gemacht

@damien: sry aber das versteh ich nicht ganz, was meinst du damit?


----------



## Unregistriert (9. Okt 2009)

Ich habe mir einfach einen Converter geschrieben:

[JAVA=42]
package org.domain.testseam.converters;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;

import org.domain.testseam.entity.Categories;
import org.jboss.seam.annotations.Name;

@Name("converterCategory")
public class ConverterCategory implements Converter {

	public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) {
		// TODO Auto-generated method stub
		int categoryId = Integer.parseInt(arg2);

		for (Categories category : org.domain.testseam.session.ApplicationBean
				.getInstance().getCategoriesList()) {
			if (category.getCategoryId() == categoryId) {
				return category;
			}
		}
		return null;
	}

	public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) {
		// TODO Auto-generated method stub
		Categories category = (Categories) arg2;
		return category.getCategoryId().toString();
	}
}



[/code]

im view:

[JAVA=42] 
            <s:decorate id="categoryIdField" template="layout/edit.xhtml">
                <ui:define name="label">Category</ui:define>
                 <h:selectOneMenu selectFirstOnUpdate="false"
			        defaultLabel="Enter some value"
			         value="#{advertsEdit.adverts.categories}" converter="#{converterCategory}">
			        <f:selectItems  value="#{advertsEdit.categoriesList}" />
			    </h:selectOneMenu>
            </s:decorate>
[/code]

Und dann einfach noch beim faces-config.xml bekannt machen..

Lg

Calvin


----------

