Java.lang.NumberFormatException: For input string: ""

Pessoal,

Estou tentando implementar um converter para um objeto, mas está dando esse erro:

[quote]
java.lang.NumberFormatException: For input string: “”
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:504)
at java.lang.Integer.parseInt(Integer.java:527)
at sgm.util.CategoriaConverter.getAsObject(CategoriaConverter.java:18)
at com.sun.faces.renderkit.html_basic.MenuRenderer.isSelected(MenuRenderer.java:719)
at com.sun.faces.renderkit.html_basic.MenuRenderer.renderOption(MenuRenderer.java:551)
at com.sun.faces.renderkit.html_basic.MenuRenderer.renderOptions(MenuRenderer.java:792)
at com.sun.faces.renderkit.html_basic.MenuRenderer.renderSelect(MenuRenderer.java:844)
at com.sun.faces.renderkit.html_basic.MenuRenderer.encodeEnd(MenuRenderer.java:298)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875)
at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:312)
at com.sun.faces.renderkit.html_basic.GridRenderer.renderRow(GridRenderer.java:185)
at com.sun.faces.renderkit.html_basic.GridRenderer.encodeChildren(GridRenderer.java:129)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:845)
at org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:55)
at org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:43)
at org.primefaces.component.fieldset.FieldsetRenderer.encodeContent(FieldsetRenderer.java:95)
at org.primefaces.component.fieldset.FieldsetRenderer.encodeMarkup(FieldsetRenderer.java:76)
at org.primefaces.component.fieldset.FieldsetRenderer.encodeEnd(FieldsetRenderer.java:53)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1763)
at javax.faces.render.Renderer.encodeChildren(Renderer.java:168)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:845)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1756)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1759)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1759)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1759)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1759)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:401)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:410)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:563)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:399)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:317)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:204)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:311)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)[/quote]

Não sei onde estou errando, estou há dias tentando salvar no BD o id de um objeto vindo do selectOneMenu, mas não consigo.

FORM:

 <h:form>
            <p:fieldset legend="Cadastro de Produto" styleClass="cadastros">                            
                <p:focus for="descricao"/>
                <h:panelGrid columns="2" id="tabela">                
                    <h:outputLabel value="Descrição:" for="descricao"/>
                    <h:inputTextarea value="#{produtoController.produto.descricao}" id="descricao"
                                     cols="60" rows="2" required="true"/>                                         
                    
                    <h:messages showDetail="#{true}" showSummary="#{true}" />
                    
                    <h:outputLabel value="Categoria:" for="categoria"/>                                                             
                    <h:selectOneMenu id="categoria" 
                                     value="#{produtoController.produto.categoria}" converter="categoriaConverter">                       
                        <f:selectItem itemLabel="Selecione..." itemValue="" noSelectionOption="true" /> 
                        <f:selectItems value="#{categoriaController.listaCategorias}" var="categorias"
                                       itemLabel="#{categorias.descricao}" itemValue="#{categorias.id}"/>                                                                                                
                    </h:selectOneMenu>                                       
                 
                    <h:outputLabel value="Estoque Mínimo:" for="estoqueMin"/>
                    <h:inputText value="#{produtoController.produto.estoqueMin}" id="estoqueMinimo" size="4" required="true"/>   

                    <h:outputLabel value="Estoque Máximo:" for="estoqueMax"/>
                    <h:inputText value="#{produtoController.produto.estoqueMax}" id="estoqueMaximo" size="4" required="true"/>   

                    <h:outputLabel value="Valor Unitário:" for="valor"/>
                    <h:inputText value="#{produtoController.produto.valor}" id="valor" size="10" required="true"/>   

                    <h:outputLabel value="Localização:" for="localizacao"/>
                    <h:inputTextarea value="#{produtoController.produto.localizacao}" id="localizacao"
                                     cols="60" rows="2" required="true"/>                             

                    <h:outputLabel value="Perecível:" for="perecivel"/>
                    <h:selectOneMenu value="#{produtoController.produto.perecivel}" id="perecivel" required="true">
                        <f:selectItem itemValue="true" itemLabel="Sim"/>
                        <f:selectItem itemValue="false" itemLabel="Não"/>                        
                    </h:selectOneMenu>                                                           

                    <h:outputLabel value="Ativo:" for="ativo"/>
                    <h:selectOneMenu value="#{produtoController.produto.ativo}" id="ativo" required="true">
                        <f:selectItem itemValue="true" itemLabel="Sim"/>
                        <f:selectItem itemValue="false" itemLabel="Não"/>                        
                    </h:selectOneMenu>

                    <h:outputLabel value="Observações:" for="obs"/>
                    <h:inputTextarea value="#{produtoController.produto.obs}" id="obs"
                                     cols="60" rows="2" required="true"/> 
                </h:panelGrid>                                   
                <h:commandButton action="#{produtoController.salvar}" value="Salvar"/>
                <h:commandButton action="#" value="Excluir" />
            </p:fieldset>        
        </h:form> 

CONVERTER:

@FacesConverter(value = "categoriaConverter", forClass = Categoria.class)
public class CategoriaConverter implements Converter {
    
    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {        
        CategoriaDao categoriaDao = new CategoriaDaoImp();
        
        return categoriaDao.getCategoria(Integer.parseInt(value));                       
    }  
    
    @Override  
    public String getAsString(FacesContext context, UIComponent component, Object value) {       
        return value.toString();  
    }  
}

Faça um teste na variável antes de chamar o DAO.

if(!value.equals("")) return categoriaDao.getCategoria(Integer.parseInt(value)); return null;

Só explicando…

Quando seu código chega no ponto

Integer.parseInt(value)

a variavel value possui uma String vazia “”, então não é possível fazer a conversão para Integer o que gera a pilha que postou…

Já tinha feito o q vc falou hugo.hlcxcx.
Mas continuo não conseguindo salvar no BD, já tentei fazer sem usar o converter, pegando o id direto, também não foi.
ERRO:

CONVERTER:

 @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {        
        
       CategoriaDao categoriaDao = new CategoriaDaoImp();
       
       if(!value.equals("")){
           return categoriaDao.getCategoria(Integer.parseInt(value));
       }
       else{
           return null;
       }
    }  
    
    @Override  
    public String getAsString(FacesContext context, UIComponent component, Object value) {       
        return value.toString();  
    }

Tente fazer a validação assim:

[code]if(!value.trim().equals("")){
return categoriaDao.getCategoria(Integer.parseInt(value));
}

return null; [/code]
Caso tenha alguma outra dúvida, basta olhar nesse post: JSF: Converter e Bean Auto Complete.

E se lembre que você retornando null, no seu MB vc terá que tratar isso.

Continua a mesma coisa. Eu tenho mesmo que usar converter?

ERRO:

XHTML:

<h:outputLabel value="Categoria:" for="categoria"/>
                    <h:selectOneMenu value="#{produtoController.produto.categoria}" 
                                     id="categoria">
                        <f:selectItems value="#{categoriaController.listaCategorias}" var="categorias"
                                       itemLabel="#{categorias.descricao}" itemValue="#{categorias.id}"/>                           
                        <f:converter converterId="categoriaConverter"/>
                    </h:selectOneMenu>

CONVERTER:

@FacesConverter(value = "categoriaConverter", forClass = Categoria.class)
public class CategoriaConverter implements Converter {
    
    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {        
        
        CategoriaDao categoriaDao = new CategoriaDaoImp();

        if (!value.trim().equals("")) {
            return categoriaDao.getCategoria(Integer.parseInt(value));
        }

        return null;
    }  
    
    @Override  
    public String getAsString(FacesContext context, UIComponent component, Object value) {       
        return value.toString();  
    }
}

CONTROLLER:

@ManagedBean(name = "produtoController")
@SessionScoped
public final class ProdutoController implements Serializable {

    private Produto produto = new Produto();    
    private ProdutoDao produtoDao = new ProdutoDaoImp();
    private List<SelectItem> listaCategorias;
    private int categoriaSelecionada;

    public ProdutoController() {
        this.produto = new Produto();
        this.produto.setCategoria(new Categoria());                
        this.produtoDao = new ProdutoDaoImp(); 
        this.listaCategorias = this.getListaCategorias();
    }

    public Produto getProduto() {
        return produto;
    }

    public void setProduto(Produto produto) {
        this.produto = produto;
    }

    public List<SelectItem> getListaCategorias() {
        ArrayList<SelectItem> lista = new ArrayList<SelectItem>();
        CategoriaDao categoriaDao = new CategoriaDaoImp();
        List<Categoria> resultado = (List<Categoria>) categoriaDao.listarAtivas();

        for (Categoria c : resultado) {
            SelectItem item = new SelectItem(c.getId(), c.getDescricao());
            lista.add(item);
        }
        return lista;
    }

    public int getCategoriaSelecionada() {
        return categoriaSelecionada;
    }

    public void setCategoriaSelecionada(int categoriaSelecionada) {
        this.categoriaSelecionada = categoriaSelecionada;
    }            
    
    public String salvar() {
        /*CategoriaDao categoriaDao = new CategoriaDaoImp();
        Categoria categoria = categoriaDao.getCategoria(4);
        categoria.setProdutos(new HashSet<Produto>());
        categoria.getProdutos().add(produto);        
        this.produto.setCategoria(categoria);*/
        this.produtoDao.save(this.produto);
        
        this.produto = new Produto();

        //Fica na mesma página
        return null;
    } 
}

MODEL:

@Entity
@Table(name = "categoria", catalog = "estoque")
public class Categoria implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id;

    @Column(name = "descricao")
    private String descricao;
    
    @Column(name = "ativo")
    private Boolean ativo;
    
    @OneToMany(mappedBy = "categoria")
    @Cascade(CascadeType.ALL)
    private Collection<Produto> produtos;

    //get e set
   
    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Categoria)) {
            return false;
        }
        Categoria other = (Categoria) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "sgm.model.Categoria[ id=" + id + " ]";
    }
@Entity
@Table(name = "produto", catalog = "estoque")
public class Produto implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id;
    
    @Lob
    @Column(name = "descricao")
    private String descricao;
    
    @Column(name = "estoque_min")
    private Integer estoqueMin;
    
    @Column(name = "estoque_max")
    private Integer estoqueMax;
    
    // @Max(value=?)  @Min(value=?)//if you know range of your decimal fields consider using these annotations to enforce field validation
    @Column(name = "valor")
    private BigDecimal valor;
    
    @Lob
    @Column(name = "localizacao")
    private String localizacao;
    
    @Column(name = "perecivel")
    private Boolean perecivel;
    
    @Column(name = "ativo")
    private Boolean ativo;
    
    @Column(name = "quantidade")
    private Integer quantidade;
    
    @Lob
    @Column(name = "obs")
    private String obs;
    
    /*@OneToMany(mappedBy = "produto")
    private List<Lote> loteList;*/
    
   /* @ManyToOne
    @JoinColumn(name = "id_unidade", referencedColumnName = "id")    
    private Unidade unidade;*/
    
    @ManyToOne
    @JoinColumn(name = "id_categoria", referencedColumnName = "id", insertable = false, updatable = false)    
    @Fetch(FetchMode.JOIN)
    @Cascade(CascadeType.PERSIST)
    private Categoria categoria;

    //get e set

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Produto)) {
            return false;
        }
        Produto other = (Produto) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "sgm.model.Produto[ id=" + id + " ]";
    }

Pessoal, consegui resolver sem o converter. Peguei o id do objeto selecionado, carreguei o objeto com esse id e setei antes de salvar. Isso é certo? Posso fazer assim? Por que tenho ou não que usar o converter?

Olha o exemplo que eu te passei.

Retirei de um livro.

Inté! \o_

Já olhei seu exemplo, várias vezes, valeu pela ajuda. Mas não consigo de jeito nenhum colocar nenhum converter para funcionar, já estou há dias nisso, já estou ficando p… com isso. Consegui sem utilizar converter e queria saber se posso fazer assim? Usar ou não usar o converter? Li na internet que é bom usar, mas não estou conseguindo.
Vou tentar mais uma vez, vou ler seu exemplo de novo e retorno aqui.
Valeu pela ajuda de vocês.

Há um tempo atrás eu usei um código que era muito parecido com o teu e tava funcionando bem
Mas eu usei o f:converter

FormaPagamento.java

[code]@FacesConverter(value = “formapagamento”)
public class FormaPagamentoConverter implements Converter {

@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
    return FormaPagamento.getDao().buscar(Integer.parseInt(value));
}

@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
    if(value instanceof FormaPagamento)
        return "" + ((FormaPagamento) value).getId();
    return "";
}

}[/code]

registrarvenda.xhtml

<h:selectOneMenu value="#{vendaBean.formaPagamento}" required="true" requiredMessage="Selecione a Forma de Pagamento" > <c:forEach items="#{globalRequest.formaPagamentoList}" var="formaPagamento"> <c:if test="#{formaPagamento.ativo}"> <f:selectItem itemLabel="#{formaPagamento.descricao}" itemValue="#{formaPagamento}" /> </c:if> </c:forEach> <f:converter converterId="formapagamento" /> </h:selectOneMenu>

Eu não mexi de novo no código mas eu acho que se você nao usar o required=true no seu h:selectOneMenu você precisa verificar no converter se a string passada é vazia que é o motivo dessa exceção que você está recebendo

Só pra constar eu fazia desse jeito que você fez e não tem problema nenhum, mas usando o converter o seu código fica mais limpo.
Se tiver tempo testa esse código ai que eu te passei

Valeu, Lucas. Vou testar o exemplo que voce deu sim e posto o resultado aqui.

Lucas, testei o código que você passou e voltei ao mesmo erro de quando eu postei essa dúvida:

Para preencher seu comboBox (selectOneMenu), você retorna uma lista de objetos normais ou uma lista de SelectItens do JSF?

Meu xhtml ficou assim:

 <h:outputLabel value="Categoria:" for="categoria"/> 
                    <h:selectOneMenu value="#{produtoController.produto.categoria}" id="categoria"
                                     required="true" requiredMessage="Por favor, selecione uma categoria par ao produto!">
                        <f:selectItem itemLabel="Selecione..." itemValue="" noSelectionOption="true" /> 
                        <f:selectItems itemValue="#{categoriaController.listaCategorias}"/>                         
                        <f:converter converterId="categoriaConverter"/>
                    </h:selectOneMenu>     

Minha lista é preenchida assim:
CONTROLLER

private ArrayList<SelectItem> getListaCategoriasAtivas() {
        ArrayList<SelectItem> lista = new ArrayList<SelectItem>();        
        List<Categoria> resultado = (List<Categoria>) this.categoriaDao.listarAtivas();

        for (Categoria c : resultado) {
            SelectItem item = new SelectItem(c.getId(), c.getDescricao());
            lista.add(item);
        }
       
        return lista;
    }

DAO:

@Override
    public List<Categoria> listarAtivas() {
        Transaction tx = null;
        Session session = HibernateUtil.openSession();
        tx = session.beginTransaction();
        session.clear();

        Criteria c = session.createCriteria(Categoria.class);
        //Restrigindo apenas as linhas salvas que estejama ativas, ou seja, com o campo ativo com 1(true)
        c.add(Restrictions.eq("ativo", true));
        c.addOrder(Order.asc("descricao"));

        List lista = c.list();

        tx.commit();

        return lista;
    }

Meu converter fiz igual ao que me passou:

[code]@FacesConverter(value = “categoriaConverter”)
public class CategoriaConverter implements Converter {

@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
    CategoriaDao categoriaDao = new CategoriaDaoImp();
  
    return categoriaDao.getCategoria(Integer.parseInt(value));
}

@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
    if(value instanceof Categoria)
        return "" + ((Categoria) value).getId();
    return "";
}

}[/code]

Pessoal, vou criar um novo tópico, pois refiz meu converter e o erro agora é outro