2

当我在 dataTable 中放置一个 selectOneMenu 时,它不会在 selectOneMenu 中显示正确的默认值。数据表绑定到 POJO 列表。POJO 实体 Badge 引用了一个我们将称为 Facility 的 POJO 实体。此 Facility 应该是行中 selectOneMenu 的选定值(该行是每个 Badge)。

以下是我的简单表格示例:

<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 是在 PostConstruct 中创建的 SelectItem 对象列表。这些在 ViewScope 中的 managedbean 中。

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;
    }

}

Here is the Facility class which has equals and hashCode implemented:

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());
    }

}

I would greatly appreciate any feedback.

4

1 回答 1

0

I found the problem and it is nothing to do with JSF.

Eclipse was loading an older version of the Facility bean class that had a programmatic mistake in its equals method. Even after fully cleaning, republishing, cleaning the working directory, restarting the web server, and restarting Eclipse this old class was still getting loaded. I restarted my computer and finally the correct class was being loaded and this problem went away.

Thanks for looking at this BalusC. Without this blog article you wrote I would be completely lost! http://balusc.blogspot.com/2007/09/objects-in-hselectonemenu.html

于 2011-03-29T17:25:59.170 回答