SelectOneMenu JSF com converter

Boa noite galera, é o seguinte estou utilizando JSF 2.0 + Primefaces

O problema é quando eu preciso editar algum dado em uma pagina que é necessário um selectOneMenu, ele não é preenchido

Estou usando converter para cadastrar através dessa pagina, e funciona tudo ok, porém quando vou editar ele não seleciona

o dado correto, fica apenas na primeira opcão. Antes quando eu pegava apenas o id do tipo de recurso funciona normal.

Segue o código.

[code] <p:selectOneMenu value="#{cadRecursosBean.selectedRecurso.tipo}" id=“itemsRecursos” converter=“entityConverter” >
<f:selectItem itemLabel=“Selecione” itemValue="#{null}" />
<f:selectItems value="#{cadRecursosBean.listaTipoRecurso}" var=“trecurso” itemLabel="#{trecurso.nome}" itemValue="#{trecurso}" />
</p:selectOneMenu>

[/code]

Acho que deu pra entender né? Obrigado.

Você verificou se o converter está funcionando bilateralmente (getAsObject e no getAsString)?

No chutometro falaria que o metodo equals da entitdade Tipo não foi definido

Bom aparentemente o converter está funcionando sim, teria alguma forma simples de testar se está tudo ok?

Realmente o código equals da entidade tipo não estava sobrescrito, adicionei ele mas continuo com o mesmo problema…

Obrigado pela atenção.

renancortes ,

Você pode postar o código do seu converter e do backing bean?
Acho que sei o problema, mas com o código fica mais fácil dizer com certeza.

Bom dia Sandro Queiroz,

Código converter

public class EntityConverter implements Converter {

    @Override
	public Object getAsObject(FacesContext ctx, UIComponent component, String value) {
         	if (value != null) {
			return component.getAttributes().get(value);
                        
		}
                
              
		return null;
	}

    @Override
	public String getAsString(FacesContext ctx, UIComponent component, Object obj) {
		if (obj != null && !"".equals(obj)) {
			String id;
			try {
				id = this.getId(getClazz(ctx, component), obj);
				if (id == null){
					id = "";
				}
				id = id.trim();
				component.getAttributes().put(id,
						getClazz(ctx, component).cast(obj));
				return id;
			} catch (SecurityException e) {
				FacesUtil.FacesMessage("SecurityException: " +e, FacesUtil.ERRO);
			} catch (IllegalArgumentException e) {
				FacesUtil.FacesMessage("IllegalArgumentException: " +e, FacesUtil.ERRO);
			} catch (NoSuchFieldException e) {
				FacesUtil.FacesMessage("NoSuchFieldException: " +e, FacesUtil.ERRO);
			} catch (IllegalAccessException e) {
				FacesUtil.FacesMessage("IllegalAccessException: " +e, FacesUtil.ERRO);
			}
		}
		return null;
	}

	private Class<?> getClazz(FacesContext facesContext, UIComponent component) {
		return component.getValueExpression("value").getType(
				facesContext.getELContext());
	}

	public String getId(Class<?> clazz, Object obj) throws SecurityException,
			NoSuchFieldException, IllegalArgumentException,
			IllegalAccessException {
		for (Field field : clazz.getDeclaredFields()) {
			if ((field.getAnnotation(Id.class)) != null) {
				Field privateField = clazz.getDeclaredField(field.getName());
				privateField.setAccessible(true);
				if (privateField.get(clazz.cast(obj)) != null) {
					return (String)field.getType()
							.cast(privateField.get(clazz.cast(obj))).toString();
				} else {
					return null;
				}
			}
		}
		return null;
	}
}

Código Bean


@ManagedBean(name="cadRecursosBean")
@ViewScoped
public class CadEqupamentosBean implements Serializable {

      public CadEqupamentosBean(){
        verificarParametros();
        listarRecursos();
        listarTipoRecurso();
        
    }

private void verificarParametros(){
        
      try{   
         
        String recursoID = FacesUtil.getUrlAttribute("recursoID");
        if(recursoID!=null){
            selectedRecurso = dao.buscaEquipamento(recursoID);
        }
        
      }catch(Exception e){
          FacesUtil.FacesMessage("Recurso não encontrado", FacesUtil.ERRO);
      } 
    }
....

Agradeço pela ajuda

Altera a implementação do getAsObject para algo tipo:

@Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) throws ConverterException {
        if (value != null && !"".equals(value) && value.replaceAll("[0-9]", "").length() == 0) {
        
          TipoRecursoDAO dao = new TipoRecursoDAO();              
          return dao.findById(Long.parseLong(value));
        }
        return null;
    }

Não funcionou dessa maneira ele nem cadastrou e nem apareceu selecionado ao editar , mas ao verificar o value ele realmente esta

com o valor id do tipo de recurso, mas não funciona… e não é possivel fazer essa conversão sem precisar buscar no banco?

Obrigado.

Você realmente precisa do converter ? Por que vc não tenta usar apenas o ID ?
Pelo que entendi vc tem uma entity Recurso e dentro dela uma referencia pra um outra entity TipoRecurso, é isso?
Provavelmente TipoRecurso tem um id do tipo Long.
Então seu código ficaria:

 <p:selectOneMenu  value="#{cadRecursosBean.selectedRecurso.tipo.id}" id="itemsRecursos">  
                     <f:selectItem    itemLabel="Selecione" itemValue="#{null}" />
                     <f:selectItems  value="#{cadRecursosBean.listaTipoRecurso}"  var="trecurso" itemLabel="#{trecurso.nome}" itemValue="#{trecurso.id}" />
 </p:selectOneMenu>

Dessa maneira vc nem precisa do converter.

Sim eu uso dessa maneira mas gostaria de melhorar o código pois sempre tenho que fazer a pesquisa no bean da seguinte forma

//preencher objeto
recurso.setTipoRecurso(dao.buscaTipoRecurso(recurso.getTipoRecurso.getId) ) ;
//depois persistir
dao.gravarRecurso(recurso);

tipo isso…

Tem certeza que vc precisa dessa linha?

//preencher objeto
recurso.setTipoRecurso(dao.buscaTipoRecurso(recurso.getTipoRecurso.getId) ) ;

Eu uso exatamente dessa forma mas sem precisar fazer essa busca, pois o id do TipoRecurso já esta setado.
Comenta essa linha e tenta salvar e depois alterar.

Sandro Queiroz realmente funcionou sem pesquisar!, estranho eu já tive problemas desse tipo por isso fazia essa pesquisa

talvez no jsf 1.2 sei lá, mas beleza assim é uma pesquisa a menos no banco

Obrigado pela ajuda!!!

Boa tarde pessoal.
Estou passando por um problema parecido, mas o que parece ser é que o meu converter não está funcionando corretamente.
Acredito que é porque estou querendo realizar a injeção de dependencia através na anotation @EJB dentro de um converter.
Isso está correto?

Segue o código do converter. Alguém pode me ajudar?


@FacesConverter(forClass = Estado.class, value="estadoConverter")  
public class EstadoConverter implements Converter{

	@EJB
	private EstadoRepository estadoRepository;
	
	@Override
	public Object getAsObject(FacesContext context, UIComponent component, String id) {
			try{
				Estado estado;
				Long idEstado = Long.parseLong(id);
				estado = this.estadoRepository.pesquisaPorId(idEstado);
				return estado;
			}
			catch(Exception e){
				throw new SisCgException("Erro ao converter Estado!");
			}
	}

	@Override
	public String getAsString(FacesContext context, UIComponent component, Object value) {
		Estado estado = (Estado) value;
		return estado.getId() + "";
	}

}

Aqui o Código do meu Managed Bean que adiciona os SelectsItems:

public List<Estado> getListaEstados(){
		
		return this.estadoRepository.pesquisarTodos();
	}
	
	public List<SelectItem> getSelectEstados(){
		List<SelectItem> listaSelect = new ArrayList<SelectItem>();
		 
		try{
			for(Estado estadoEach :  this.getListaEstados()){
				SelectItem si = new SelectItem();
				si.setLabel(estadoEach.getNome());
				si.setValue(estado.getId());
				
				listaSelect.add(si);
			}
			
			return listaSelect;
			
		} catch(Exception e){
			throw new SisCgException("Não foi possível obter a lista de Estados");
		}
		
	}

Aqui o código do meu xhtml, o componente que chama o método do managed bean

<p:outputLabel value="Estado" for="enderecoEstadoSelect" />
<p:selectOneMenu id="enderecoEstadoSelect" style="width:300px"
	value="#{clienteBean.estado}" converter="estadoConverter">
	<f:selectItem itemValue="" itemLabel="Selecione..." />
	<f:selectItems value="#{clienteBean.listaEstados}" />
	<p:ajax update="enderecoCidadeSelect" />
</p:selectOneMenu>

tem alguma forma de eu usar o selectOneMenu sem usar o converter?