Search code examples
javavalidationjsfrichfacesconverters

rich:select shows "Value is not valid option" after selecting and converting the item to an object


I list a collection of elements of type Test (from my domain) in a rich:select using the following code:

test.xtml

<rich:select value="#{testBean.test}" id="cmbTest"
    converter="#{testConverter}" enableManualInput="false">
    <f:selectItems value="#{testBean.all}" var="test" itemLabel="#{test.name}" />
</rich:select>
<rich:message for="cmbTest" />
<h:commandButton id="btnSave" action="#{testBean.save}" value="Save" />

I also have a custom jsf-converter to convert the select string values into objets of type Test and vice versa:

TestConverter.java

@Component
@Scope("request")
public class TestConverter implements Converter {
    @Override
    public Object getAsObject(FacesContext facescontext, UIComponent uicomponent, String value) {
        if (value == null) return null;
        return new Test(Integer.parseInt(value), "test" + value);
    }

    @Override
    public String getAsString(FacesContext facescontext, UIComponent uicomponent, Object obj) {
        if (obj == null) return null;
        return ((Test) obj).getId().toString();
    }
}

(As you may notice, I'm using Spring) The backing-bean for the xhtml file is defined as follows:

TestBean.java

@Controller("testBean")
@Scope("session")
public class TestBean {
    private Test test;
    private List<Test> all; 

    public TestBean() {
        all = new ArrayList<Test>();
        for (int i = 0; i < 15; i++) { 
            all.add(new Test(1, String.format("test%d", i)));    
        }
    }

    public Test getTest() {
        return test;
    }

    public void save() {
        System.out.println("Save");
    }

    public List<Test> getAll() {
        return all;
    }
}

When I press the "Save" button after selecting a valid item, I get the validation error: "Value is not a valid option", as shown below:

enter image description here

I have debugged the Converter getAsObject call and it works fine, it returns a valid Test instance as expected (in fact, this "test" project is an isolated case for a work project where I first found this problem, and in that project the converter successfully uses an injected service to retrieve the object from database).

Obviously the bean save method is never called as the view get stuck in the jsf validation fase with this error.

Tried to replace rich:select with h:selectOneMenu but is the same. I have surfed a lot of jsf-converter tutorials/docs/refs but I still don't know what could I be doing wrong.

I'm using maven and the Richfaces BOM configuration as pointed here, replaced the version with 4.2.2.Final though (hoping the update could fix it)

I posted the test project here

Any help would be really appreciated, I have spent so much time trying to find a solution for this, maybe is something simple/stupid but I'm just tired of debuging/searching


Solution

  • You need to implement equals() and hashCode() inside your Test class so that JSF can find your selected and converted item in the list of the items. After conversion, JSF will compare the selected item against the items in the list and raise this error if it does not find it.