Ainda não tem acesso? Estude com a gente! Matricule-se
Ainda não tem acesso? Estude com a gente! Matricule-se

Solucionado (ver solução)

Erro ao tentar executar dao.quantidadeDeElementos

Fiz a configuração do CDI de acordo com as aulas, mas estou retornando um erro quando entro na página livro.xhtml, que executa o método dao.quantidadeDeElementos. Segue o erro:

out 12, 2017 8:53:18 PM com.sun.faces.application.view.FaceletViewHandlingStrategy handleRenderException
GRAVE: Error Rendering View[/livro.xhtml]
java.lang.NullPointerException
    at br.com.caelum.livraria.modelo.LivroDataModel.<init>(LivroDataModel.java:22)
    at br.com.caelum.livraria.bean.LivroBean.<init>(LivroBean.java:40)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at org.jboss.weld.injection.ConstructorInjectionPoint.newInstance(ConstructorInjectionPoint.java:119)
    at org.jboss.weld.injection.ConstructorInjectionPoint.invokeAroundConstructCallbacks(ConstructorInjectionPoint.java:92)
    at org.jboss.weld.injection.ConstructorInjectionPoint.newInstance(ConstructorInjectionPoint.java:78)
    at org.jboss.weld.injection.producer.AbstractInstantiator.newInstance(AbstractInstantiator.java:28)
    at org.jboss.weld.injection.producer.BasicInjectionTarget.produce(BasicInjectionTarget.java:116)
    at org.jboss.weld.injection.producer.BeanInjectionTarget.produce(BeanInjectionTarget.java:180)
    at org.jboss.weld.bean.ManagedBean.create(ManagedBean.java:158)

Existe um outro erro também, se ajudar...

Outro erro:

out 12, 2017 8:53:18 PM org.apache.catalina.core.StandardWrapperValve invoke
GRAVE: Servlet.service() for servlet [Faces Servlet] in context with path [/jsf-livraria-cdi] threw exception [null] with root cause
java.lang.NullPointerException
    at br.com.caelum.livraria.modelo.LivroDataModel.<init>(LivroDataModel.java:22)
    at br.com.caelum.livraria.bean.LivroBean.<init>(LivroBean.java:40)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at org.jboss.weld.injection.ConstructorInjectionPoint.newInstance(ConstructorInjectionPoint.java:119)
    at org.jboss.weld.injection.ConstructorInjectionPoint.invokeAroundConstructCallbacks(ConstructorInjectionPoint.java:92)
    at org.jboss.weld.injection.ConstructorInjectionPoint.newInstance(ConstructorInjectionPoint.java:78)

Ambos estão dizendo que o dao.quantidadeDeElementos() retorna nulo, e não sei o motivo pelo qual ele está retornando nulo.

Por gentileza, quem conseguir me ajudar.

4 respostas

Olá Gustavo,

Veja o que está nulo, se é o atributo dao ou é alguma coisa dentro do método quantidadeDeElementos().

Confere também se o atributo dao está com @Inject.

Qualquer coisa, poste o código aqui para que consigamos analisar melhor.

Olá Diego,

Como é o CDI que está gerenciando o acoplamento entre as classes, não consigo saber o que exatamente está nulo. Não sei se existe alguma forma de saber. Já verifiquei todas as marcações e estão de acordo com o vídeo. Fiz bastante coisa e nada, sempre o mesmo erro. Não sei o que pode ser.

Segue o link do gist para visualizar as classes. https://gist.github.com/GustavoPrimolan/e100a7a2c1bb4da904c982a5a0628b76

solução

Olá Gustavo, como eu disse no outro post, sabemos que o CDI espera uma classe com construtor padrão, então tente substituir:

public LivroDataModel(){
        super.setRowCount(dao.quantidadeDeElementos());
    }

por:

@PostConstruct
    void init() {
        super.setRowCount(dao.quantidadeDeElementos());
    }

Ah, e de uma verificada na sua classe LivroBean, se você estiver instanciando LivroDataModel na mão, remova o new, e use a Injeção com @Inject

@Inject
    private LivroDataModel livroDataModel;

Faça essa mudança, que irá funcionar.

Qualquer coisa comente ae...!

OI Gustavo, tudo bem?

o problema é que vc não deveria chamar esse método no construtor, o construtor precisa ser o default. Então como podemos chamar o dao na inicialização da classe sem o construtor?

@PostConstruct
    public void init() {
        super.setRowCount(this.dao.quantidadeDeElementos());
    }

utilizando um método com a anotação @PostConstruct.

Dessa forma quando o DataModel for instanciado vai chamar o método com essa anotação.

Espero ter ajudado =)