Safwen Khalloufi
Safwen Khalloufi

Reputation: 97

selectOneMenu default value issue using converter

I'm using <p:selectOneMenu> as follows:

<p:selectOneMenu id="choixProgramme" converter="#{programmeConverter}"
value="#{programmeController.selectedProgramme}">
<f:selectItem itemLabel="Select One" itemValue="" />
<f:selectItems value="#{programmeController.listProgrammes}"
    var="programme" itemLabel="#{programme.codeProgImmobilier}"
    itemValue="#{programme}" />
<p:ajax update="dataTableBien" />

I would like to show Select One message, but I get this error:

java.lang.String cannot be cast to xx.xxxxx.xxxx.xxxx.dto.ProgrammeDto

I tried this solution but I still have the same problem.

Edited

I added noSelectionOption to my <f:selectItem>:

But I have a conversation problem in getAsObject().

 java.lang.NumberFormatException: For input string: "Select One"

Edited

My converter:

@Override
public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2) {
    if (arg2 == null || arg2.isEmpty()) {
        return null;
    }

    String programme = arg2;
    Long value = Long.valueOf(programme);
    ProgrammeDto result = new ProgrammeDto();
    result = programmeService.findById(value);
    return result;
}

@Override
public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) {

    if (arg2 == null) {
        return "";
    }
    if(arg2 instanceof ProgrammeDto) {
        if (((ProgrammeDto) arg2).getIdProgramme() == null) {
            return "";
        }
    }

            ProgrammeDto programme = new ProgrammeDto();

    if(arg2 instanceof ProgrammeDto) {

        programme = (ProgrammeDto) arg2;
        String codeProgramme = programme.getIdProgramme().toString();
        return (codeProgramme != null) ? String.valueOf(codeProgramme) : null;
    } else throw new ConverterException("Something wrong!" + arg2.hashCode() + arg2.toString());

}

How can I achieve this?

Upvotes: 1

Views: 3499

Answers (1)

BalusC
BalusC

Reputation: 1108642

You're specifying an item value of an empty string and you've most likely the following in your converter's getAsString():

public String getAsString(FacesContext context, UIComponent component, Object modelValue) {
    return ((ProgrammeDto) modelValue).getId();
}

However, an empty string can never be represented as a valid ProgrammeDto reference.

Either use an item value of #{null} instead of an empty string:

<f:selectItem itemLabel="Select One" itemValue="#{null}" />

or set the noSelectionOption attribute to true:

<f:selectItem itemLabel="Select One" noSelectionOption="true" />

Chances are that the converter's getAsString() will now throw NullPointerException instead of ClassCastException, but it should be obvious enough as to how to fix that. Just check if it's not null before casting and obtaining the desired field.

public String getAsString(FacesContext context, UIComponent component, Object modelValue) {
    return (modelValue != null) ? ((ProgrammeDto) modelValue).getId() : null;
}

See also:


Update: as per your updated question, it seems that PrimeFaces is not considering the noSelectionOption and treating label as item value. In that case, you'd need to either explicitly specify an item value of #{null}:

<f:selectItem itemLabel="Select One" itemValue="#{null}" noSelectionOption="true" />

or to check in the getAsObject() if the submitted value is parseable as a Long:

if (arg2 == null || !arg2.matches("[0-9]+")) {
    return null;
}

Upvotes: 2

Related Questions