【发布时间】:2011-10-18 10:29:19
【问题描述】:
早前就该主题发表过一篇文章 (Display values in drill-down SelectOneMenus)。我最初想到的问题与对象转换器无关。
我有两个 selectOneMenu 相互依赖,Sector -> Category。当我坚持持有一个部门和类别的后台业务对象时,一切都按预期工作。即使在当前用户会话终止并且用户再次登录并编辑之前保存的业务对象之后。
当实体管理器刷新对象并且用户想要从数据库中再次显示扇区、类别时,就会出现问题。扇区selectOneMenu 显示其值,但不显示类别selectOneMenu 值。尽管支持 bean 具有来自数据库的正确值。
是什么让selectOneMenu在从数据库而不是从内存中加载某些持久值/对象时不显示它们?
编辑.xhtml
<h:outputLabel value="Sector:" />
<h:selectOneMenu id="sectorSelector" value="#{activityController.selected.category.sector}" title="#{bundle.CreateSectorLabel_sectorName}" valueChangeListener="#{activityController.changeSectorMenu}" immediate="true">
<a4j:ajax event="change" execute="@this categoryMenu" render="categoryMenu"/>
<f:selectItems value="#{sectorController.itemsAvailableSelectOne}"/>
</h:selectOneMenu>
<h:outputLabel value="Category:" />
<h:selectOneMenu id="categoryMenu" value="#{activityController.selected.category}" title="#{bundle.CreateSectorLabel_sectorName}"
binding="#{activityController.categoryMenu}"
required="true" requiredMessage="#{bundle.CreateCategoryRequiredMessage_sector}">
<f:selectItems value="#{activityController.categorySelection}"/>
</h:selectOneMenu>
类别的控制器 bean
@ManagedBean(name = "categoryController")
@SessionScoped
public class CategoryController implements Serializable{
....
@FacesConverter(forClass = Category.class)
public static class CategoryControllerConverter implements Converter {
@Override
public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
if (value == null || value.length() == 0) {
return null;
}
CategoryController controller = (CategoryController) facesContext.getApplication().getELResolver().
getValue(facesContext.getELContext(), null, "categoryController");
return controller.ejbFacade.find(getKey(value));
}
java.lang.Integer getKey(String value) {
java.lang.Integer key;
key = Integer.valueOf(value);
return key;
}
String getStringKey(java.lang.Integer value) {
StringBuffer sb = new StringBuffer();
sb.append(value);
return sb.toString();
}
@Override
public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
if (object == null) {
return null;
}
if (object instanceof Category) {
Category o = (Category) object;
return getStringKey(o.getIdCategory());
}
else {
throw new IllegalArgumentException("object " + object + " is of type " + object.getClass().getName() + "; expected type: " + CategoryController.class.getName());
}
}
}
POJO 对象的一部分
...
public class Category implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "idCategory")
private Integer idCategory;
...
@Override
public boolean equals(Object object) {
if (!(object instanceof Category)) {
return false;
}
Category other = (Category) object;
if ((this.idCategory == null && other.idCategory != null) || (this.idCategory != null && !this.idCategory.equals(other.idCategory))) {
return false;
}
return true;
}
创建 SelectItem[] 数组的函数
public static SelectItem[] getSelectItems(List<?> entities, boolean selectOne) {
int size = entities.size();
SelectItem[] items;
int i = 0;
if (selectOne) {
items = new SelectItem[size + 1];
items[0] = new SelectItem("", ResourceBundle.getBundle("/resources/Bundle").getString("Select_item"));
i++;
} else {
items = new SelectItem[size];
}
for (Object x : entities) {
items[i++] = new SelectItem(x, x.toString());
}
return items;
}
【问题讨论】:
-
这表示您的
Category的equals()丢失或损坏。显示它。 -
Category equals() 之类的接缝永远不会被调用。但该部门的人确实如此。此外,不会在 Category bean 类上调用 getAsString() 方法。为什么当它们看起来相同时不会为一个类调用equals,而是为另一个类调用equals?
-
这反过来表明
<f:selectItems>不包含Category对象作为值。也许您将List<String>而不是List<Category>传递给您的getSelectItems()?