NullPointerException Java JPA CDI Tomcat

5

Good afternoon, guys. I'm developing a Java test application with JPA, CDI and Tomcat. I created a basic test class and I'm 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 correctly with @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've also created a Webservice class called WSP Specialty, where the ODBC injection injection does not work.

Does anyone know how to fix this? Why? Any way out? Below are the files and classes.

Template 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 ...
}

Code of the SpecialTourism class.

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();
    }

}

Test 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();        
    }
}

WS Special Class.

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 beans.xml file is created, but empty, as recommended.

    
asked by anonymous 29.07.2016 / 21:52

2 answers

0

Note your class EspecialidadeWS with @javax.enterprise.context.RequestScoped to work as web service.

EDIT:

In my projects, I use RESTEasy together with CDI to make the injection work for you. Let's go: it's also necessary to create a class that extends to javax.ws.rs.core.Application in your project:

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, note EspecialidadeWS also with @javax.ws.rs.Path("/especialidade") . If everything works, you should be able to access your web service via link , for example.

    
01.08.2016 / 18:21
0

If you're trying to use main, it will not work!

Because: You are using a feature 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 or reuses. Basically speaking, running on tomcat is it that makes a "new Object ()" in the entityManager within SpecialData for you.

Running on main you will have to create the EntityManager instance using EntityManagerFactory and pass it to your SpecialtiesDAO, just because you do not have this little robot doing the service for you.

    
29.07.2016 / 22:50