JSF + EJB + Converter = NullPointerException

Pessoal,

Há muito tempo estou tentando resolver um problema num converter, por favor, me digam o que há de errado.

Tenho um converter:

@FacesConverter(value="categoriaConverter", forClass=Categoria.class)
public class CategoriaConverter implements Converter{

	@EJB
	private CategoriaDAO categoriaDAO;
	
	@Override
	public Object getAsObject(FacesContext context, UIComponent component, String value) throws ConverterException {
		int idCategoria;
		try {
			idCategoria = Integer.parseInt(value);
		} catch (NumberFormatException exception) {
			throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Type the name of a Categoria and select it (or use the dropdow)", "Type the name of a Categoria and select it (or use the dropdow)"));
		}
		return categoriaDAO.retornaCategoriaPorId(idCategoria);
	}

	@Override
	 public String getAsString(FacesContext context, UIComponent component, Object object) throws ConverterException {  
        if(object != null && object instanceof Categoria) {  
            return ((Categoria)object).getId().toString();  
        }  
        return null;  
    }  
}

Que está jogando a excessão de NullPointerException bem na linha 15.

  • Para qualquer id de categoria é exibida a mensagem (qualquer id existente na minha base de dados).

Meu xhtml:

<p:selectOneMenu value="#{cadastroAnuncioAction.categoriaSelecionada}" id="comboCategoria" converter="categoriaConverter">  
   <f:selectItem itemLabel="Selecione uma categoria" itemValue="" />  
   <f:selectItems value="#{cadastroAnuncioAction.listaCategoria}" 
	            	var="categoria" 
	            	itemLabel="#{categoria.nome}" 
	            	itemValue="#{categoria}"/>
   </p:selectOneMenu> 

<p:commandButton value="Cadastrar" update="@form" action="#{cadastroAnuncioAction.cadastrarAnuncio()}" ajax="false" /> 

Na minha classe categoria já implementei equals e hashCode.

E abaixo a mensagem de erro.

javax.servlet.ServletException
	javax.faces.webapp.FacesServlet.service(FacesServlet.java:606)
	org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:62)
	br.com.pacote.filter.DefaultUserPagesFilter.doFilter(DefaultUserPagesFilter.java:35)
root cause

java.lang.NullPointerException
	br.com.pacote.converter.CategoriaConverter.getAsObject(CategoriaConverter.java:28)
	com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getConvertedValue(HtmlBasicInputRenderer.java:171)
	com.sun.faces.renderkit.html_basic.MenuRenderer.convertSelectOneValue(MenuRenderer.java:202)
	com.sun.faces.renderkit.html_basic.MenuRenderer.getConvertedValue(MenuRenderer.java:319)
	org.primefaces.component.selectonemenu.SelectOneMenuRenderer.getConvertedValue(SelectOneMenuRenderer.java:55)
	javax.faces.component.UIInput.getConvertedValue(UIInput.java:1030)
	javax.faces.component.UIInput.validate(UIInput.java:960)
	javax.faces.component.UIInput.executeValidate(UIInput.java:1233)
	javax.faces.component.UIInput.processValidators(UIInput.java:698)
	javax.faces.component.UIForm.processValidators(UIForm.java:253)
	javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1214)
	javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1214)
	javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1214)
	javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1214)
	javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1214)
	javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:1172)
	com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:76)
	com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
	com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
	javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
	org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:62)
	br.com.pacote.filter.DefaultUserPagesFilter.doFilter(DefaultUserPagesFilter.java:35)
note The full stack trace of the root cause is available in the JBoss Web/7.0.13.Final logs.

Como ele menciona um filter, segue também o filter:

package br.com.pacote.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import br.com.pacote.model.Usuario;
 
public class DefaultUserPagesFilter extends AbstractFilter implements Filter {
 
    @Override
    public void destroy() {
 
    }
 
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        
        Usuario usuario = null;
        
        usuario = (Usuario) req.getSession(true).getAttribute("usuario");
 
        if(usuario == null || (!usuario.isUser() && !usuario.isAdmin())){
            accessDenied(request, response, req);
            return;
        }
 
        chain.doFilter(request, response);
    }
 
    @Override
    public void init(FilterConfig arg0) throws ServletException {
 
    }
}

Mostra como vc está montando o List<SelectItem> de categorias.

Na verdade não é um List e sim um List, segue:


private List<Categoria> listaCategoria;

public List<Categoria> getListaCategoria() {
   return listaCategoria;
}

montando por um outro outro método:

public void carregarCategorias(){
    this.listaCategoria = categoriaService.listaCategoriaPorSegmento(1);
}

Pessoal,

Uma questão sobre o mesmo problema. Posso utilizar @EJB dentro de Converter? Senão, qual seria a melhor abordagem quando é utilizado DAO genérico e Entity?

Obrigado.

[quote=leandroguima]Pessoal,

Uma questão sobre o mesmo problema. Posso utilizar @EJB dentro de Converter? Senão, qual seria a melhor abordagem quando é utilizado DAO genérico e Entity?

Obrigado.[/quote]
Não, ainda não pode usar.

Acho que na versão 2.2 você já poderá utilizar dos recursos de injeção nos seus Converters e Validators, mas na versão atual não.

As duas sugestões são:

1 - Fazer um lookup manual, através de um Service Locator ou o que você quiser.
2 - Anotar o Converter com @ManagedBean, que é uma versão bem mais gambiarrística que a acima, mas funciona e é muito mais fácil de implementar.

[quote=leandroguima]Na verdade não é um List e sim um List, segue:


private List<Categoria> listaCategoria;

public List<Categoria> getListaCategoria() {
   return listaCategoria;
}

montando por um outro outro método:

public void carregarCategorias(){ this.listaCategoria = categoriaService.listaCategoriaPorSegmento(1); } [/quote]

Ora,então ai está o problema.

Vc não deve montar um List e sim um List

Algo do tipo:


   List<SelectItem> selectCategorias;
   for(Categoria c : dao.getCategorias()){
       selectCategorias.add(new SelectItem(c,c.getNome));
}

raf4ever / Rodrigo Sasaki,

Muito obrigado pela ajuda.

O meu principal problema era a injeção do EJB no Converter, ou seja, não funciona.

raf4ever,

Para efeito de teste, fiz um List e o que você sugeriu List. Os dois funcionaram perfeitamente.

Rodrigo Sasaki,

Não consegui fazer o lookup pelo Converter, estava tomando vários erros ao tentar criar o InitialContext.

Por fim acabei seguindo exatamente o que estava no post http://www.guj.com.br/java/259653-conversor–ejb-resolvido e tudo funcionou direitinho.

Mais uma vez obrigado a todos pela ajuda.

Um abraço.