selectOneMenu в dataTable, значение по умолчанию не устанавливается должным образом

Когда я помещаю selectOneMenu в dataTable, он не отображает правильное значение по умолчанию в selectOneMenu. Datatable привязан к списку POJO. Значок объекта POJO ссылается на объект POJO, который мы будем называть Facility. Это средство должно быть выбранным значением selectOneMenu в строке (строка представляет собой каждый значок).

Ниже приведен мой простой пример таблицы:

<h:dataTable id="examp" value="#{managedBean.badges}" var="badge">
            <h:column rowHeader="rowie">
                <h:selectOneMenu value="#{badge.facility}" id="col1">
                    <f:converter converterId="facilityConverter" />
                    <f:selectItems value="#{managedBean.facilities}"   
                         />
                </h:selectOneMenu> 
            </h:column>         
        </h:dataTable>

SelectItems — это список объектов SelectItem, созданных в PostConstruct. Они находятся в моем управляемом компоненте, который находится в ViewScope.

public class ListBadges extends BaseBean {

private List<Badge> badges = new ArrayList<Badge>();
private List<SelectItem> facilities = new ArrayList<SelectItem>();

public ListBadges() {
        getBadgesFromDatabase(true);
}

@PostConstruct
public void init() {
    if (facilities.size() <= 0) {
        try {
            List<Facility> facilityBeans = FacilityHelper.getFacilities();
            for (Facility fac : facilityBeans) {
                facilities.add(new SelectItem(fac, fac.getFacilityName()));
            }
        } catch (tException e) {
            log.error("ListBadges.init(): " + e.getMessage());
            e.printStackTrace();
        }
    }
}

public void getBadgesFromDatabase(boolean forceRefresh) {
    if (forceRefresh || badges == null || badges.isEmpty())
        badges = BadgeHelper.getBadgeList();
}           
///
/// Bean Properties
///

public List<Badge> getBadges() {
    return badges;
}

public void setBadges(List<Badge> badges) {
    this.badges = badges;
}

public List<SelectItem> getFacilities() {
    return facilities;
}

public void setFacilities(List<SelectItem> facilities) {
    this.facilities = facilities;
}

Проходя код, я подтверждаю, что все данные верны. В моем преобразователе я проверил правильность аргументов, переданных в getAsString, поэтому он должен был определить правильный элемент.

@FacesConverter("facilityConverter")
public class FacilityConverter implements Converter {

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String from) {
        try {
            ELContext elContext = FacesContext.getCurrentInstance().getELContext();
            ListBadges neededBean = 
                (ListBadges) context.getApplication().getELResolver().getValue(elContext, null, "managedBean");
            long id = Long.parseLong(from);
            for (SelectItem sItem : neededBean.getFacilities()) {
                Facility facility = (Facility)sItem.getValue();
                if (facility.getFacilityId() == id)
                    return facility;
            }
        } catch (Exception e) {

        }
        return null;
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        try {
            Facility facility = (Facility)value;
            return facility.getFacilityId() + "";
        } catch (Exception e) {

        }
        return null;
    }

}

Вот класс Facility, в котором реализованы equals и hashCode:

public class Facility implements java.io.Serializable {

    private static final long serialVersionUID = 1L;

    private long facilityId;
    private String facilityName;
    private String address1;
    private String address2;
    private String city;
    private String state;
    private String postalCode;
    private String url;
    private String phone;
    private String siteManager;

    public Facility() {
    }

    public Facility(String facilityName) {
        this.facilityName = facilityName;
    }

    public Facility(String facilityName,
            String address1, String address2, String city, String state,
            String postalCode, String url, String phone, String siteManager) {
        this.facilityName = facilityName;
        this.address1 = address1;
        this.address2 = address2;
        this.city = city;
        this.state = state;
        this.postalCode = postalCode;
        this.url = url;
        this.phone = phone;
        this.siteManager = siteManager;
    }

    public long getFacilityId() {
        return this.facilityId;
    }

    public void setFacilityId(long facilityId) {
        this.facilityId = facilityId;
    }

    public String getFacilityName() {
        return this.facilityName;
    }

    public void setFacilityName(String facilityName) {
        this.facilityName = facilityName;
    }

    public String getAddress1() {
        return this.address1;
    }

    public void setAddress1(String address1) {
        this.address1 = address1;
    }

    public String getAddress2() {
        return this.address2;
    }

    public void setAddress2(String address2) {
        this.address2 = address2;
    }

    public String getCity() {
        return this.city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getState() {
        return this.state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getPostalCode() {
        return this.postalCode;
    }

    public void setPostalCode(String postalCode) {
        this.postalCode = postalCode;
    }

    public String getUrl() {
        return this.url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getSiteManager() {
        return siteManager;
    }

    public void setSiteManager(String siteManager) {
        this.siteManager = siteManager;
    }

    @Override
    public boolean equals(Object o) {
        if (!(o instanceof Facility) || (o == null))
            return false;

        if (o == this)
            return true;

        Facility obj = (Facility)o;
        return obj.getFacilityId() == this.getFacilityId();
    }

    @Override
    public int hashCode() {
        return (new Long(this.getFacilityId()).hashCode()) ^
            ((this.getAddress1() == null) ? 0 : this.getAddress1().hashCode()) ^
            ((this.getAddress2() == null) ? 0 : this.getAddress2().hashCode()) ^
            ((this.getCity() == null) ? 0 : this.getCity().hashCode()) ^
            ((this.getFacilityName() == null) ? 0 : this.getFacilityName().hashCode()) ^
            ((this.getPhone() == null) ? 0 : this.getPhone().hashCode()) ^
            ((this.getPostalCode() == null) ? 0 : this.getPostalCode().hashCode()) ^
            ((this.getSiteManager() == null) ? 0 : this.getSiteManager().hashCode()) ^
            ((this.getUrl() == null) ? 0 : this.getUrl().hashCode());
    }

}

Буду очень признателен за любые отзывы.


person maple_shaft    schedule 29.03.2011    source источник
comment
В будущем, пожалуйста, обратите особое внимание на ваше аргументированное отношение к рассматриваемому фреймворку/API :) Это сильно демотивирует других публиковать ответы. Я подметал и то, и другое. Однако не стесняйтесь откатиться, если вы не согласны.   -  person BalusC    schedule 29.03.2011
comment
Прошу прощения BalusC. Вы были правы, убрав лишнее из моего поста. Я очень расстроен своей личной ситуацией, и у меня напряженный срок. Я не хотел критиковать Мохарру.   -  person maple_shaft    schedule 29.03.2011


Ответы (1)


Я нашел проблему, и она не имеет ничего общего с JSF.

Eclipse загружал более старую версию класса bean-компонента Facility, в методе equals которого была программная ошибка. Даже после полной очистки, повторной публикации, очистки рабочего каталога, перезапуска веб-сервера и перезапуска Eclipse этот старый класс все еще загружался. Я перезагрузил свой компьютер, и, наконец, загрузился правильный класс, и эта проблема исчезла.

Спасибо за внимание к этому BalusC. Без этой статьи в блоге, которую вы написали, я был бы полностью потерян! http://balusc.blogspot.com/2007/09/objects-in-hselectonemenu.html

person maple_shaft    schedule 29.03.2011
comment
@BalusC Спасибо за статью, у меня была та же проблема, я понял, что значение должно быть установлено в f: selectItems, а не в p: selectOneMenu. :D - person Oh Chin Boon; 18.02.2012