jsfjsf-2primefacesselectonemenuselectmanymenu

How do UISelectOne and UISelectMany components preselect defaults in f:selectItems


I know how to preselect <p:selectOneMenu>, in selected value should be one of the objects from <f:selectItems>, but how does this component work under the hood and can I change this behavior?

In my case I've a duplicate object, actually this is two objects with the same values but created twice and selected object in <p:selectOneMenu> differs from object from <f:selectItems> and it doens't recognize it. Most likely I will change my design so, it will point to same object but in case I can't do it due to legacy code or etc, how can I change the behavior of <p:selectOneMenu> that it will compare objects by id for example?

I'd thought that converter responsible for it, but when it rendered it doesn't enter on getAsObject method only getAsString, so I guess that there's something different, but what?

Thank you


Solution

  • It uses Object#equals() for that. You can change (fix) this behavior by implementing it accordingly on your entity.

    private Long id;
    
    @Override
    public boolean equals(Object other) {
        return (other != null && getClass() == other.getClass() && id != null)
            ? id.equals(getClass().cast(other).id)
            : (other == this);
    }
    

    Don't forget the hashCode() to satisfy the equals-hashCode contract.

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

    If you can't change the existing entity for some unclear reason, wrap it in your own DTO.

    The converter only converts between the entity and its unique String representation for usage in HTML output and HTTP request parameters and has therefore no influence on preselection. It has only influence on potential Validation Error: Value is not valid trouble.

    See also: