tags:

views:

83

answers:

1

I am setting up a form using JSF (I'm pretty new at this) and I am getting a Validation Error: Value is not valid message on one of the fields. This field is actually a separate object (as I will show below) that has a custom converter.

Here is what I have (with non-relevant code removed):

I have a Citation class:

@ManagedBean(name="citation")
public class Citation {
    private int id;
    private Status status;

    // getters and setters
}

I also have a Status class that you see referenced in the Citation class:

@ManagedBean(name="status")
public class Status {
    private int id;
    private String name;

    // getters and setters

    public List<Status> getAllStatuses() {
        Session session = HibernateUtil.getCurrentSession();
        session.beginTransaction();
        session.clear();

        Query query = session.createQuery("from Status");
        List<Status> statuses = query.list();

        try {
            session.getTransaction().commit();
        } catch (HibernateException e) {
            // TODO: handle exception
            session.getTransaction().rollback();
        }

        return statuses;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) return false;
        if (!(obj instanceof Status)) return false;

        if (this.id == ((Status)obj).getId()) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public int hashCode() {
        return this.name.hashCode();
    }
}

Then for my form, I have:

<h:selectOneMenu id="citation_status" value="#{citation.status}">
    <f:selectItems value="#{status.allStatuses} var="s" itemValue="#{s.id}" itemLabel="#{s.name}" />
</h:selectOneMenu>
<h:message for="citation_status" />

Lastly, for my converter, I have:

@FacesConverter(forClass=Status.class)
public class StatusConverter implements Converter {
    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        // uses Hibernate to get the Status object (using a breakpoint in Eclipse, I have verified that this works)
        // I can post this code if needed, but just trying to keep it short :)
    }

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

Now when I get to my form and submit, I get the Validation Error next to the Status. I'm pretty new at this and thanks to @BalusC, I'm this far along.

Any help is greatly appreciated.

+2  A: 

Validation Error: Value is not valid

In case of <h:selectOneMenu>, you will get this when error whenever the selected item does not match any of the items available in the list. I.e. selectedItem.equals(selectItem) has never returned true for any of the items.

Since it's apparently a custom object (the Status class), did you implement its Object#equals() (and #hashCode()) properly? You can if necessary let the IDE (Eclipse/Netbeans) autogenerate them.

See also:


Update: after having a closer look at your code, it turns out that you're actually submitting #{s.id} instead of #{s} (the whole Status object). Fix the itemValue accordingly and it should work (if equals() is still doing its job properly).

BalusC
I'm assuming that I have implemented them correctly. I have updated the code above to include them. Maybe I am doing it incorrectly?
Jared
You only forgot `if (obj == this) return true` for the case there's no `id`. The `instanceof` also returns `false` for `null`, so the `obj == null` is superfluous. The `hashCode()` is a bit weak. But this shouldn't be the problem here. Can you ensure that the `getAllStatuses()` is been called during validations phase and that exactly the same list is been returned as during initial request (to display the form)?
BalusC
I'm not really sure where I should put a breakpoint to check the validations phase? I added the code that is used to get the list of `Status` objects above. I assume that this code should return the same thing in both phases.
Jared
Check answer update.
BalusC
That did the trick. Amazing what a difference a few characters can make :) Thanks again for all of your help!
Jared
You're welcome :)
BalusC
I peeked a bit in your question history and it turns out that I've already [answered](http://stackoverflow.com/questions/3711572/jsf-select-items-from-subclass/3711621#3711621) this in your previous question! ;)
BalusC