3

I have this SelectOneMenu:

<h:selectOneMenu value="#{orderController.requestVO.requestSituation}">
    <f:converter converterId="ComboConverter"/>
    <f:selectItems value="#{orderController.requestSituation}" var="requestSituation"
                                                   itemLabel="#{requestSituation.description}" itemValue="#{requestSituation}" />
</h:selectOneMenu>

The requestSituation is a ArrayList filled with RequestSituationVO It is populated correctly, generating this HTML:

<select name="j_idt14:j_idt20" size="1">
        <option value="13">Pedido Recusado</option>
    <option value="11">Pedido Validado</option>
    <option value="12" selected="selected">Pedido Confirmado</option>
    <option value="12" selected="selected">Pedido Faturado</option>
</select>

I have this Converter and here is where I'm confused, I've read a lot and I know what it has to do but not how it works.

Here it is:

@FacesConverter(value = "ComboConverter", forClass = RequestSituationVO.class)
public class ComboConverter implements Converter
{

    private static RequestSituationVO requestSituationVO = new RequestSituationVO();

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value)
    {
        requestSituationVO.setId(Integer.valueOf(value));
        requestSituationVO = (RequestSituationVO) new RequestSituationBO().getRequestSituation(requestSituationVO).toArray()[0];
        return (RequestSituationVO) requestSituationVO;
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value)
    {
        requestSituationVO = (RequestSituationVO) value;
        String teste = String.valueOf(requestSituationVO.getId());
        return teste;
    }
}

When I submit my page, I think the SelectOneMenu will automatically set the value for the requestSituation method from requestVO. But when I submit, I get a message Value not valid referencing to my SelectOneMenu.

What I need is to set the selected value on my RequestSituationVO so I can send it to the Business method.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555

2 Answers2

10

Your converter is fine. You would otherwise have gotten a conversion error something like

Conversion Error setting value 'com.example.RequestSituationVO@hashcode' for 'null Converter'

You've a validation error. This particular one will be thrown when the Object#equals() test of the selected item hasn't returned true for any of the available items in the list. JSF is checking that to prevent attacks by tampered requests. This can in your particular case have the following causes:

  • The equals() method of the RequestSituationVO class is missing or broken.
  • The #{orderController.requestSituation} has incompatibly changed in between the request of displaying the form and the request of processing the form submit.

I think that it's the former. Given the fact that your RequestSituationVO has an Integer id property which uniquely identifies the object, this should do:

@Override
public boolean equals(Object other) {
    return (other instanceof RequestSituationVO) && (id != null)
        ? id.equals(((RequestSituationVO) other).id)
        : (other == this);
}

@Override
public int hashCode() {
    return (id != null)
        ? (this.getClass().hashCode() + id.hashCode())
        : super.hashCode();
}

If the equals() method is not the problem, then it's the latter cause. This can be solved by making sure that the #{orderController.requestSituation} returns exactly the same list during displaying the form and processing the form submit. This can be achieved by placing the bean in the view scope and not doing the business logic in the getter at all. Or if it actually represents applicationwide data, you could refactor it to a separate application scoped bean.

See also

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
3

It looks like you forgot to implement equals and hashCode in RequestSituation.
This is very important, as JSF will compare the submitted value against all the given items.

If you don't implement equals, it thinks the submitted item is not in the list,
so it rejects it. (The value is not valid.)

Alba Mendez
  • 4,432
  • 1
  • 39
  • 55