1

Of five options in a selectOneMenu I chose the second option and persisted the entity. On edit the persisted entity selectOneMenu always has the last option as its value.

For example,

<h:selectOneMenu value="#{userHome.user.leader}">
    <f:selectItems value="#{userHome.availableLeaders}" var="leader" itemLabel="#        {leader.name}" itemValue="#{leader}"/>
</h:selectOneMenu>

where availableLeaders is a list of users populated @PostConstruct method.

I am expecting the selectOneMenu to have the second option(chosen) on edit.

@FacesConverter(forClass = User.class, value = "userConverter")
public class UserConverter implements Converter {

    public UserConverter() {
    }

    @Override
    public Object getAsObject(FacesContext context, UIComponent component,
            String value) {
            EntityManagerFactory emf =     Persistence.createEntityManagerFactory("DefaultPersistenceUnit");
            EntityManager em = emf.createEntityManager();
            Query q = em.createQuery("select query");
        return q.resultList().get(0);
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component,
            Object value) {
        return ((User) value).getName();
    }}

In User.java

public boolean equals(Object other) {
    if (this.getClass().isInstance(other)) {
        return true;
    } else {
        return false;
    }
}

public int hashCode() {
    HashCodeBuilder builder = new HashCodeBuilder();
    builder.append(getId());
    builder.append(getName());
    return builder.toHashCode();
}
Gnanam
  • 513
  • 2
  • 10
  • 21

1 Answers1

4

Look here:

public boolean equals(Object other) {
    if (this.getClass().isInstance(other)) {
        return true;
    } else {
        return false;
    }
}

Your equals() method is definitely broken. This returns true for every other User object, even though it internally holds a completely different user ID/name. So the selected item matches every available select item value. That's why you see the last item being preselected everytime.

Assuming that the id property is unique for every user, then the equals() method should at its simplest rather look like this:

public boolean equals(Object other) {
    if (!(other instanceof User)) {
        return false;
    }

    if (other == this) {
        return true;
    }

    if (id != null) {
        return id.equals(((User) other).id);
    }

    return false;
}

which can also be summarized as follows

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

Hint: a bit decent IDE like Eclipse can autogenerate equals() (and hashCode()) method.

See also:

Community
  • 1
  • 1
BalusC
  • 992,635
  • 352
  • 3,478
  • 3,452
  • A missing equals method might also give similar symptoms (e.g. a wrongly selected item) – dvtoever Feb 28 '13 at 13:09
  • 1
    @dvtoever: http://stackoverflow.com/questions/9069379/validation-error-value-is-not-valid/9069660#9069660 – BalusC Feb 28 '13 at 13:09