NullPointerException Java JPA CDI Tomcat

Good afternoon, guys. I am developing a Test Java application with JPA, CDI and Tomcat. I have created a basic test class and I am getting the following error.

Erro: Exception in thread "main" java.lang.NullPointerException
    at br.com.hcancerbarretos.espec.dao.EspecialidadesDAO.getEspecialidades(EspecialidadesDAO.java:16)
    at br.com.hcancerbarretos.espec.testes.Teste.main(Teste.java:13)

The EspecialidadeDAO is null, not being injected properly with the @Inject. The strangest thing is that if I create a JSF page and display the values in a dataTable, everything that has @Inject is injected normally. I also created a Webservice class called EspecialidadeWS, where the dependency injection of Specialty does not work.

Can anyone tell me how to fix this? Why does it happen? Any way out? Below are the files and classes.

Model Class:

import java.io.Serializable;
import javax.persistence.*;
import java.util.Date;

@Entity
@NamedQuery(name="Especialidade.findAll", query="SELECT e FROM Especialidade e")
public class Especialidade implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @Column(name="ESPECEALIDADE_ID")
    private long especialidadeId;

    private String descricao;

    @Temporal(TemporalType.DATE)
    @Column(name="DT_ALT")
    private Date dtAlt;

    @Temporal(TemporalType.DATE)
    @Column(name="DT_INCL")
    private Date dtIncl;

    private String sigla;

    @Column(name="USU_ALT")
    private String usuAlt;

    @Column(name="USU_INCL")
    private String usuIncl;

    public Especialidade() {
    }

    //getters and setters ...
}

Specialty class code.

import java.util.List;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import br.com.hcancerbarretos.espec.model.Especialidade;

public class EspecialidadesDAO {

    @Inject
    private EntityManager em;

    public List<Especialidade> getEspecialidades() {
        return em.createNamedQuery("Especialidade.findAll", Especialidade.class).getResultList();
    }

    public String getEspecialidadePorCodigo(long codigo) {
        return em.createQuery("select e.descricao From Especialidade e Where e.especialidadeId = :codigo", String.class)
                .setParameter("codigo", codigo).getSingleResult();
    }
}

Class EntityManagerProducer:

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.context.RequestScoped;
import javax.enterprise.inject.Disposes;
import javax.enterprise.inject.Produces;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

@ApplicationScoped
public class EntityManagerProducer {

    private EntityManagerFactory factory;

    public EntityManagerProducer() {
        this.factory = Persistence.createEntityManagerFactory("Especialidade");
    }

    @Produces
    @RequestScoped
    public EntityManager createEntityManager() {
        return factory.createEntityManager();
    }

    public void closeEntityManager(@Disposes EntityManager manager) {
        manager.close();
    }

}

Heads Class:

import java.util.List;
import br.com.hcancerbarretos.espec.dao.EspecialidadesDAO;
import br.com.hcancerbarretos.espec.model.Especialidade;

public class Teste {

    public static void main(String[] args) {        
        EspecialidadesDAO dao = new EspecialidadesDAO();
        List<Especialidade> especialidades = dao.getEspecialidades();        
    }
}

Specialty Classews.

import javax.inject.Inject;
import br.com.hcancerbarretos.espec.dao.EspecialidadesDAO;

public class EspecialidadeWS {

    @Inject
    private EspecialidadesDAO dao;

    public String getEspecialidade(long codigo){
        System.out.println("DAO " + dao);
        return dao.getEspecialidadePorCodigo(codigo);
    }   
}

File web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    version="2.5">

    <display-name>Especialidade</display-name>

    <welcome-file-list>
        <welcome-file>index.jsf</welcome-file>
        <welcome-file>index.xhtml</welcome-file>
    </welcome-file-list>

    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.jsf</url-pattern>
    </servlet-mapping>

    <listener>
        <listener-class>org.jboss.weld.environment.servlet.Listener</listener-class>
    </listener>
    <resource-env-ref>
        <resource-env-ref-name>BeanManager</resource-env-ref-name>
        <resource-env-ref-type>javax.enterprise.inject.spi.BeanManager</resource-env-ref-type>
    </resource-env-ref>

</web-app>

File META-INF\context.xml:

<?xml version="1.0" encoding="UTF-8"?>
<Context>
    <!-- disables storage of sessions across restarts -->
    <Manager pathname="" />
    <Resource name="BeanManager" auth="Container"
        type="javax.enterprise.inject.spi.BeanManager" factory="org.jboss.weld.resources.ManagerObjectFactory" />
</Context>

The file beans.xml is created, but empty, as practice.

Author: Reginaldo, 2016-07-29

3 answers

Write down your class EspecialidadeWS with @javax.enterprise.context.RequestScoped to function as web service.

EDIT:

In my projects I use RESTEasy in conjunction with CDI to make the injection you want work. Come on: you also need to create, in your project, a class that extends to javax.ws.rs.core.Application:

package abc;

import abc.EspecialidadeWS;

import javax.ws.rs.core.Application;
import java.util.HashSet;
import java.util.Set;

public class AppRs extends Application {

    private Set<Class<?>> classes;

    public AppRs() {
        classes = new HashSet<>();
        classes.add(EspecialidadeWS.class);
    }

    @Override
    public Set<Class<?>> getClasses() {
        return classes;
    }
}

No web.xml:

<!--  RESTEasy  -->
<listener>
    <listener-class>
        org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
    </listener-class>
</listener>
<servlet>
    <servlet-name>RESTEasy Servlet</servlet-name>
    <servlet-class>
        org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
    </servlet-class>
    <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>br.com.t2tecnologia.AppRs</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>RESTEasy Servlet</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<context-param>
    <param-name>resteasy.servlet.mapping.prefix</param-name>
    <param-value>/rest</param-value>
</context-param>
<context-param>
    <param-name>resteasy.injector.factory</param-name>
    <param-value>org.jboss.resteasy.cdi.CdiInjectorFactory</param-value>
</context-param>

No pom.xml (maven):

<!--  CDI (esse você já deve ter)  -->
<dependency>
    <groupId>org.jboss</groupId>
    <artifactId>jandex</artifactId>
    <version>2.0.1.Final</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>org.jboss.weld.servlet</groupId>
    <artifactId>weld-servlet</artifactId>
    <version>2.3.2.Final</version>
    <scope>runtime</scope>
</dependency>
<!--  RESTEasy  -->
<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-jaxrs</artifactId>
    <version>3.0.16.Final</version>
</dependency>
<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-servlet-initializer</artifactId>
    <version>3.0.16.Final</version>
</dependency>
<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-cdi</artifactId>
    <version>3.0.16.Final</version>
</dependency>
<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-jackson-provider</artifactId>
    <version>3.0.16.Final</version>
</dependency>
<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.9.13</version>
</dependency>

Class EspecialidadeWS:

@Path("/especialidade")
@GET
public class EspecialidadeWS {

    @Inject private EspecialidadesDAO dao;

    @GET
    @Path("/get/{codigo}")
    public String getEspecialidade(@PathParam("codigo") long codigo){
        return dao.getEspecialidadePorCodigo(codigo);
    }   
}

Finally, write down EspecialidadeWS also with @javax.ws.rs.Path("/especialidade"). If everything works, you should be able to access your web service via http://localhost:8080/seu_projeto/rest/especialidade/get/1 , for example.

 0
Author: Victor T., 2016-08-01 20:07:06

If you're trying to use the main method it won't work!

Because: you are using a resource called CDI, which is basically a module running in your application container that whenever an instance annotated with @EJB or @Inject is used it intercepts the thread and passes an instance that it creates itself, or repurposes. Basically speaking, running on tomcat is the one that makes a" new Object () " in the entityManager within Specialityfor you.

Rolling no main you will have to create the instance of EntityManager using EntityManagerFactory and pass it into your Specializadesdao, precisely because it does not have this little robot doing the service for you.

 0
Author: CleitonCardoso, 2016-08-03 20:40:08

Try This

public class EspecialidadeWS {

    @Inject
    private EspecialidadesDAO dao;

    public String getEspecialidade(long codigo){
        try{
            String codigo = dao.getEspecialidadePorCodigo(codigo);
            return codigo;
        }catch (NullPointerException e) {
            // TODO: handle exception
            return ''
        }
    }   
}

You are not treating the code in case the specialty does not exist. Another thing I could observe is that the attribute "description" and others is not mapped in its Entity. Mapeie...

@Column(name="ESPECEALIDADE_ID")
private String descricao;
 0
Author: Murilo Medeiros, 2019-05-21 02:00:02