0

I got folowing message:

Value is no String (class=org.xxx.Foo, value=org.xxx.Foo@366d5595) and component j_id17:j_id114:j_id125with path: {Component-Path : [Class: org.ajax4jsf.framework.ajax.AjaxViewRoot,ViewId: /foo.xhtml][Class: org.ajax4jsf.ajax.html.Include,Id: j_id17][Class: javax.faces.component.html.HtmlForm,Id: j_id114][Class: javax.faces.component.html.HtmlSelectOneMenu,Id: j_id125]} does not have a Converter.

Xhtml:

<h:selectOneMenu value="#{bar.foo}">
     <f:selectItem itemValue="#{bar.foos}" />
</h:selectOneMenu>

Foo is:

import javax.faces.model.SelectItem;
@Audited
@Entity
@Table(name= "foo")
@AccessType("property")
public class Foo extends SelectItem implements Serializable{
     ....
}

Why do i need a converter to convert from SelectItem to SelectItem?

Aritz
  • 30,971
  • 16
  • 136
  • 217
Grim
  • 1,938
  • 10
  • 56
  • 123
  • Because HTML and HTTP can't pass around Java objects. They can only pass around characters which is in Java represented by `String`. A `Converter` can convert between that `String` and the desired Java object. By the way, that `extends SelectItem` is unnecessary and nonsense. – BalusC Feb 14 '14 at 12:30

1 Answers1

1

The problem arises when JSF tries to glean the selected value from Foo during display and when it tries to get Foo back from the selected value during a postback. As BalusC mentioned, extending SelectItem isn't a good approach. You have one of two regular options: manually handling the selection or using converters.

Converters are wonderful for adapting pretty much any type of Object so that they can be directly referenced and presented via UI elements. Unfortunately, converters may require extra steps when a conversion isn't simple.

I noticed the @Entity annotation, so I'm assuming you are trying to display a list of records from which the user can choose. 90% of the time, such selections are intended to get a record's primary key rather than the record itself so that it can be used in subsequent queries or business logic. For such situations a manual selection is more effective. However, if you also need to get record content, then a converter is better suited as it would handle the lookup logic and let your business logic work directly with the record.

I'm not going to dictate which method you should choose, but since your original problem was centered around the manual approach, I'll offer this solution. Let's assume your new simplified Foo looks like this.

public class Foo {
    private long id;
    private String label;

    public Foo( long id, String label ) {
        this.id = id;
        this.label = label;
    }

    public long getId() {
        return id;
    }

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

    public String getLabel() {
        return label;
    }

    public void setLabel( String label ) {
        this.label = label;
    }
}

A simple FooCntrl bean as given below would provide presentation information and handle the selection's postback.

@Named
@ViewScoped
public class FooCntrl implements Serializable {
private long selected = 0;

    // Stub for what an EntityManager would normally provide.
    public List<Foo> getRecords () {
        List<Foo> fooList = new ArrayList<Foo>();
        fooList.add( new Foo( 11, "Paul" ) );
        fooList.add( new Foo( 23, "John" ) );
        fooList.add( new Foo( 32, "George" ) );
        fooList.add( new Foo( 47, "Ringo" ) );
        return fooList;
    }

    public long getSelected() {
        return selected;
    }

    public void setSelected( long selected ) {
        this.selected = selected;
        System.out.println( "You picked record id: " + selected );
    }

    public List<Foo> getFooList() {
        return getRecords();
    }
}

This in turn drives your UI selection menu.

...
<h:form>
    <h:selectOneMenu value="#{fooCntrl.selected}">
        <f:selectItem itemValue="0" itemLabel="Select One..." />
        <f:selectItems value="#{fooCntrl.fooList}" var="r" itemLabel="#{r.label}" itemValue="#{r.id}"/>
    </h:selectOneMenu>
    <h:commandButton value="Submit" />
</h:form>
...

This is just one variant. I'm certain that some will disagree with it and recommended converters all the way or even recommend another manual approach. My goal is to give you something that you can move forward with. I'll leave it up to you to refine your design methodology and style at your own pace :).

Frelling
  • 3,287
  • 24
  • 27