Użycie „Proszę wybrać” f: selectItem z wartością null / empty wewnątrz a p: selectOneMenu

Zapełniam<p:selectOneMenu/> z bazy danych w następujący sposób.

<p:selectOneMenu id="cmbCountry" 
                 value="#{bean.country}"
                 required="true"
                 converter="#{countryConverter}">

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

    <f:selectItems var="country"
                   value="#{bean.countries}"
                   itemLabel="#{country.countryName}"
                   itemValue="#{country}"/>

    <p:ajax update="anotherMenu" listener=/>
</p:selectOneMenu>

<p:message for="cmbCountry"/>

Domyślnie wybrana opcja, po załadowaniu tej strony,

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

Konwerter:

@ManagedBean
@ApplicationScoped
public final class CountryConverter implements Converter {

    @EJB
    private final Service service = null;

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        try {
            //Returns the item label of <f:selectItem>
            System.out.println("value = " + value);

            if (!StringUtils.isNotBlank(value)) {
                return null;
            } // Makes no difference, if removed.

            long parsedValue = Long.parseLong(value);

            if (parsedValue <= 0) {
                throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "", "Message"));
            }

            Country entity = service.findCountryById(parsedValue);

            if (entity == null) {
                throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_WARN, "", "Message"));
            }

            return entity;
        } catch (NumberFormatException e) {
            throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "", "Message"), e);
        }
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        return value instanceof Country ? ((Country) value).getCountryId().toString() : null;
    }
}

Gdy pierwszy element z menu jest reprezentowany przez<f:selectItem> jest zaznaczone, a następnie formularz jest przesyłanyvalue uzyskane wgetAsObject() metoda jestSelect która jest etykietą<f:selectItem> - pierwszy element na liście, który nie jest intuicyjnie oczekiwany.

KiedyitemValue atrybut<f:selectItem> jest ustawiony na pusty łańcuch, a następnie rzucajava.lang.NumberFormatException: For input string: "" wgetAsObject() metoda, nawet jeśli wyjątek został dokładnie złapany i zarejestrowanyConverterException.

Wydaje się, że to działa, kiedyreturn oświadczeniegetAsString() jest zmieniony z

return value instanceof Country?((Country)value).getCountryId().toString():null;

do

return value instanceof Country?((Country)value).getCountryId().toString():"";

null jest zastępowany pustym łańcuchem, ale zwraca pusty ciąg, gdy dany obiekt jestnullz kolei powoduje inny problem, jak pokazanotutaj.

Jak sprawić, aby takie konwertery działały prawidłowo?

Próbowałem także zorg.omnifaces.converter.SelectItemsConverter ale to nie miało znaczenia.

questionAnswers(6)

yourAnswerToTheQuestion