JSF Nur Strings in rich:select ?

inv_zim

Gesperrter Benutzer
Hallo,

ich arbeite mich in das Thema gerade erst ein, deshalb kann es sein, dass ich den Wald vor lauter Bäumen nicht sehe. Zum Googlen fehlen mir anscheinend die richtigen Worte, weil ich auch nichts gescheites finde.

Ich schreibe zurzeit eine kleine Musikverwaltung als Test. Ich möchte jetzt mit meinem ersten Formular eine neue Band anlegen. Code:

Artist.java
Java:
@Entity
//ohne Getter und Setter, für die Übersichtlichkeit
public class Artist implements Serializable {

	private static final long serialVersionUID = -454999573669270892L;

	/**
	 * Eindeutige ID fuer den <code>Artist</code>. Wird von der Datenbank
	 * generiert (Stichwort "AutoIncrement").
	 */
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private int id;

	/**
	 * Der Bandname (z.B. "The Hives", "Tool", "Queens of the Stone Age")
	 */
	@Column
	@NotNull
	private String name;

	/**
	 * Das <code>Genre</code> der Band.
	 */
	@ManyToOne
	@NotNull
	private Genre genre;

	/**
	 * Das Herkunftsland der Band.
	 */
	@ManyToOne
	@NotNull
	private Country origin;

ArtistDao.java
Java:
@Stateless
public class ArtistDao {
	
	@Inject
	@DataRepository
	private EntityManager entityManager;
	
	public void persist(Artist artist) {
		entityManager.persist(artist);
	}
	
	@SuppressWarnings("unchecked")
	public List<Artist> getAll() {
		return entityManager.createQuery("SELECT a FROM Artist a").getResultList();		
	}
	
	public Artist getArtist(int id) {
		Query query = entityManager.createQuery("SELECT a FROM Artist a WHERE id = ?");
		query.setParameter(0, id);
		return (Artist) query.getSingleResult();
	}	
}

ArtistBean.java
Java:
@Named("artistBean")
@SessionScoped
public class ArtistBean implements Serializable{
	
	private static final long serialVersionUID = -523574992609221740L;
	
	@Inject
	private ArtistDao artistDao;	
	private Artist artist = new Artist();
	
	public void save() {
		artistDao.persist(artist);
		artist = new Artist();
	}
	
	public Artist getArtist() {
		return artist;
	}

	public void setArtist(Artist artist) {
		this.artist = artist;
	}
}

Auszug aus home.xhtml
HTML:
<h:form id="artistEdit">
	Name:
	<br />
	<h:inputText value="#{artistBean.artist.name}" id="name" />
	<h:message for="name" styleClass="errorMessage" />
	<br />				
	Genre:
	<br />
	<rich:select id="genre" value="#{artistBean.artist.genre}"
		required="true" itemClass="de.concerto.ConCerto.model.Genre">
		<f:selectItems value="#{genreBean.all}" />
	</rich:select>
	<br />				
	Herkunft: 
	<br />
	<rich:select id="country" defaultLabel="Bitte auswählen"
		value="#{artistBean.artist.origin}" required="true"
		itemClass="de.concerto.ConCerto.model.Country" enableManualInput="true">
		<f:selectItems value="#{countryBean.all}" />
	</rich:select>
	<h:commandButton action="#{artistBean.save}" value="Submit" />
</h:form>

Die Exception:
Code:
javax.faces.component.UpdateModelException: javax.el.ELException: /home.xhtml @25,67 value="#{artistBean.artist.genre}": Cannot convert Grunge of type class java.lang.String to class de.concerto.ConCerto.model.Genre
	javax.faces.component.UIInput.updateModel(UIInput.java:848)
	javax.faces.component.UIInput.processUpdates(UIInput.java:730)
	javax.faces.component.UIForm.processUpdates(UIForm.java:268)
	javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1109)
	javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1109)
	javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1109)
	javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1109)
	javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1109)
	javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1109)
	javax.faces.component.UIViewRoot.processUpdates(UIViewRoot.java:1218)
	com.sun.faces.lifecycle.UpdateModelValuesPhase.execute(UpdateModelValuesPhase.java:74)
	com.sun.faces.lifecycle.Phase.doPhase(Phase.java:97)
	com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:114)
	javax.faces.webapp.FacesServlet.service(FacesServlet.java:308)
	org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:67)

Kann ich also in der Select Box nur Strings benutzen, bzw. liefert er mir nur die toString() Values zurück? Ich habe schon versucht mit ItemClass zu arbeiten, aber irgendwie führt das auch nicht zum Erfolg.

Gruß,

Tim
 
Zuletzt bearbeitet:
Ich weiß nicht wie das bei RichFaces ist aber bei "normalen" JSF's muss man dafür eine Converter-Klasse schreiben die das Converter-Interface implementiert.

Converter
 
Zuletzt bearbeitet:
Hey, vielen Dank!

Ich habe Converter jetzt beim schnellen Googlen auch im Zusammenhang mit RichFaces gefunden, das hilft mir weiter. Ich werde mich morgen mal reinlesen.

Einen schönen Abend noch,

Tim
 
Hi,

ich muss mich jetzt doch nochmal melden. Das mit den Convertern klappt gut, im Debugger sehe ich auf jeden Fall, dass die Methode "getAsObject" das richtige Objekt zurückgibt.

Jetzt habe ich Probleme mit der Validierung, ich bekomme bei beiden <rich:select> Komponenten die Meldung: "Überprüfungsfehler: Wert ist ungültig". Die Setter der zuständigen Beans werden nicht angesprochen.

Ich habe schon versucht, eigene Validatoren an diese Felder anzuhängen, diese werden auch problemlos durchlaufen, aber trotzdem erhalte ich dies Benachrichtigungen, die Felder wären ungültig. Auf welche Art und weise überprüfen die JSF das? Kann ich die Default-Validatoren irgendwie abschalten?
 
Es scheint so das du die equals-Methode in deiner Entity nicht implementiert hast -> die Methode wird intern aufgerufen.


Schau dir mal dieses Bsp. an
The BalusC Code: Objects in h:selectOneMenu

->
Please note the Object#equals() implementation. This is very important for JSF. After conversion, it will compare the selected item against the items in the list. As the Object#equals() also require Object#hashCode(), this is implemented as well.

Grüße
 

Zurück
Oben