Сделал пост ранее об этой теме ( Отображение значений в раскрывающемся списке SelectOneMenus ).Проблема, которая не связана с конвертерами объектов, как я сначала подумал.
У меня есть два selectOneMenu
в зависимости друг от друга, сектор -> категория.Когда я сохраняю фоновый бизнес-объект, который содержит сектор и категорию, все работает как положено.Даже после того, как текущий пользовательский сеанс завершается, и пользователь снова входит в систему и редактирует предыдущий сохраненный бизнес-объект.
Проблема возникает, когда менеджер сущностей сбрасывает объекты, и пользователь хочет снова отобразить сектор, категорию избаза данных.Сектор selectOneMenu
отображает свое значение, как и должно быть, но значение категории selectOneMenu
не отображается.Хотя базовый компонент имеет правильное значение из базы данных.
Что заставляет selectOneMenu
не отображать определенные постоянные значения / объекты, когда они загружаются из базы данных, а не из памяти?
Edit.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>
Бин контроллера для категории
@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;
}