Pessoal, boa tarde.
Tenho um crud basico com alguns campos e um SelectOneMenu.
Para o SelectOneMenu foi criado um converter, ja que o valor selecionado que preciso é a entidade “Categoria” e não o id ou uma string.
Está dessa forma:
<h:selectOneMenu id="txtCategoria" value="#{perguntaBean.pergunta.categoria}" converter="EntityConverter" disabled="#{perguntaBean.bloquearTexto}">
<f:selectItem itemValue="" itemLabel="Selecione uma categoria"/>
<f:selectItems value="#{perguntaBean.categoriasItens}" var="o" itemLabel="#{o.categoria}" itemValue="#{o}"/>
</h:selectOneMenu>
O problema está quando realizo uma consulta, onde são listados vários itens cadastrados em um dataTable.
Para cada linha tenho um command buttton que seta os valores da linha selecionada nos campos do formulario, conforme a seguir:
<a4j:commandButton id="btnExcluir"
value="#{label['btn.excluir']}" image="/Images/delete.png"
type="submit" styleClass="ImgExcluir"
reRender="txtPergunta,txtPerguntaPesquisa,txtTipo,txtCategoria,txtOrdem,btnCancelar,btnGravar,btnNovo,btnFiltrar">
<a4j:actionparam name="crudEx" value="CRUD_DELETE" assignTo="#{perguntaBean.crud}" />
<a4j:actionparam name="codigo" value="#{perguntaTo.codigo}" assignTo="#{perguntaBean.pergunta.codigo}" />
<a4j:actionparam name="status" value="#{perguntaTo.status}" assignTo="#{perguntaBean.pergunta.status}"/>
<a4j:actionparam name="categoria" value="#{perguntaTo.categoria}" assignTo="#{perguntaBean.pergunta.categoria}"/>
</a4j:commandButton>
Para todos os campos funcionam, o problema é com o SelectOneMenu que não é carregado!! 
Alguém sabe como resolver isso??
Obrigado!
Posta o código no controller tbm
Do controller tá bem simples, apenas populando as listas.
public List<SelectItem> getCategoriasItens() {
if (categoriasItens == null || categoriasItens.isEmpty()) {
if (categorias == null || categorias.isEmpty()) {
categorias = delegate.getCategoriaService().findCategoriasByEmpresaId(getProgectIdFromSession());
}
for (Categoria categoria : categorias) {
categoriasItens.add(new SelectItem(categoria, categoria.getCategoria()));
}
}
return categoriasItens;
}
O converter, qu na verdade foi extraído daqui
http://www.rponte.com.br/2008/07/26/entity-converters-pra-da-e-vender/
está assim:
public class SimpleEntityConverter implements Converter {
public Object getAsObject(FacesContext ctx, UIComponent component, String value) {
if (value != null) { return this.getAttributesFrom(component).get(value); }
return null;
}
public String getAsString(FacesContext ctx, UIComponent component, Object value) {
if (value != null && !"".equals(value)) {
BaseEntity entity = (BaseEntity) value;
// adiciona item como atributo do componente
this.addAttribute(component, entity);
Long codigo = entity.getCodigo();
if (codigo != null) { return String.valueOf(codigo); }
}
return (String) value;
}
protected void addAttribute(UIComponent component, BaseEntity o) {
String key = o.getCodigo().toString(); // codigo da entidade como chave neste caso
this.getAttributesFrom(component).put(key, o);
}
protected Map<String, Object> getAttributesFrom(UIComponent component) {
return component.getAttributes();
}
}
Exemplo de Converter
@FacesConverter(value = “converterPerfil”)
public class ConvertPerfil implements Converter {
@Override
public Object getAsObject(FacesContext context, UIComponent component,
String value) {
if (value != null && !value.equals("")) {
PerfilDao dao = new PerfilDao();
System.out.println("to no converter");
Perfil p = null;
p = dao.findPessoaByNome(value);
return p;
}
System.out.println("to no null");
return null;
}
@Override
public String getAsString(FacesContext context, UIComponent component,
Object value) {
if (value == null || value.equals("")) {
return "";
} else {
return String.valueOf(((Perfil) value).getPerfil());
}
}
No selectitem, vc pode apenas criar uma arraylst e passar para o <h:sele
private List<Aro_Roda> listarRodas = new ArrayList<>();
public List<Aro_Roda> getListarRodas() {
this.listarRodas=dao.listar();
return listarRodas;
}
Olá, obrigado pela resposta.
Mas fazendo isso me retornou a seguinte exceção
java.lang.IllegalArgumentException: Argument Error: An option for component txtCategoria was not an instance of javax.faces.model.SelectItem. Type found: java.util.ArrayList.
Não preciso mesmo passar para o SelectOneMenu um lista de SelectItem?
Posta novamente o código, para verifcar como ficou. verifica se o arraylist esta sendo montado com os dados do banco.
Ficou dessa forma:
public class ConverterCategoria implements Converter {
private ServicesDelegate delegate = (ServicesDelegate) SpringApplicationContext.getBean("servicesDelegate");
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
System.out.println("getAsObject: values = " + value);
if (value != null && !value.equals("")) {
System.out.println("to no converter");
Categoria c = null;
List<Categoria> cats = delegate.getCategoriaService().findCategoriasByNome(value);
if (cats != null && !cats.isEmpty()) {
c = cats.get(0);
}
return c;
}
System.out.println("to no null");
return null;
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
System.out.println("getAsString: values = " + value);
if (value == null || value.equals("")) {
return "";
} else {
return String.valueOf(((Categoria) value).getCategoria());
}
}
}
O array esta ok.
Mas não é necessário converter para SelectItem?
Deixando o coverter dessa forma só que passando o list de selectitem, funciona igual antes.
Não sei se ficou claro na primeira explicação, mas meu problema é o seguinte:
O selectOneMenu da forma como estava fazendo é carregado normalmente, todos os itens aparecem na listagem.
O problema é quando em determinada ação do usuário (quando clica em um botão) seja selecionado um item da listagem automaticamente.
Preciso que todos os campos do formulário sejam carregados nessa ação, para todos funcionam, menos para o SelectOneMenu.
Obrigado.