0

I get a Nullpointer Exception for the EntityManager that I inject in my Bean. I already searched for solutions, but couldn't find anything in the posts, that helped me out. Also I don't understand why the error message is saying, that the error occured in ExampleServlet, which I don't have in my application.

My DAO Bean is called by a method, which is invoked by a odata handler which is registered in the PersonServlet with:

 public void initData() {
    PersonDAO psDAO = new PersonDAO();
    psDAO.getAllPersons();
 }

What could be the reason for the error in my case?

Error:

2017-01-11T18:46:58.721+0000|Severe: [http-listener-1(5)] ERROR test.personservice.web.PersonServlet - Server Error occurred in ExampleServlet
2017-01-11T18:46:58.722+0000|Severe: java.lang.NullPointerException
    at test.personservice.dao.PersonDAO.getAllPersons(PersonDAO.java:21)
    at test.personservice.data.Storage.initSampleData(Storage.java:94)
    at test.personservice.data.Storage.<init>(Storage.java:30)
    at test.personservice.web.PersonServlet.service(PersonServlet.java:35)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:416)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:283)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206)
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:283)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:132)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:111)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:536)
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:591)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571)
    at java.lang.Thread.run(Thread.java:745)
2017-01-11T18:46:58.723+0000|Warning: StandardWrapperValve[PersonServlet]: Servlet.service() for servlet PersonServlet threw exception
java.lang.NullPointerException
    at test.personservice.dao.PersonDAO.getAllPersons(PersonDAO.java:21)
    at test.personservice.data.Storage.initSampleData(Storage.java:94)
    at test.personservice.data.Storage.<init>(Storage.java:30)
    at test.personservice.web.PersonServlet.service(PersonServlet.java:35)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:318)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:416)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:283)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:459)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:167)
    at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206)
    at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180)
    at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:235)
    at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:283)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:132)
    at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:111)
    at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
    at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:536)
    at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56)
    at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:591)
    at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571)
    at java.lang.Thread.run(Thread.java:745)

Bean

@Stateless
public class PersonDAO {

    @PersistenceContext
    private EntityManager em;

    public List<Person> getAllPersons() {

        return 
            em.createQuery("SELECT p FROM T_Person p", Person.class).getResultList();

    }

}

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="PersonService" transaction-type="JTA">
    <jta-data-source>jdbc/PersonDB</jta-data-source>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
            <property name="hibernate.hbm2ddl.auto" value="create"/>
            <property name="hibernate.show_sql" value="yes"/>
        </properties>
    </persistence-unit>
</persistence>

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>test</groupId>
    <artifactId>PersonService</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>PersonService Maven Webapp</name>
    <url>http://maven.apache.org</url>

    <properties>
        <!-- <javax.version>3.1</javax.version> -->
        <odata.version>4.0.0</odata.version>
        <slf4j.version>1.7.7</slf4j.version>
    </properties>

    <dependencies>

        <!-- <dependency> -->
        <!-- <groupId>javax.servlet</groupId> -->
        <!-- <artifactId>servlet-api</artifactId> -->
        <!-- <version>${javax.version}</version> -->
        <!-- <scope>provided</scope> -->
        <!-- </dependency> -->

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>

        <dependency>
            <groupId>javax.ejb</groupId>
            <artifactId>javax.ejb-api</artifactId>
            <version>3.2</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.2.5.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>5.3.4.Final</version>
        </dependency>



        <dependency>
            <groupId>org.apache.olingo</groupId>
            <artifactId>odata-server-api</artifactId>
            <version>${odata.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.olingo</groupId>
            <artifactId>odata-server-core</artifactId>
            <version>${odata.version}</version>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.olingo</groupId>
            <artifactId>odata-commons-api</artifactId>
            <version>${odata.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.olingo</groupId>
            <artifactId>odata-commons-core</artifactId>
            <version>${odata.version}</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>${slf4j.version}</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.11</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <finalName>PersonService</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

PersonServlet

public class PersonServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;
    private static final Logger LOG = LoggerFactory.getLogger(PersonServlet.class);

    protected void service(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
      try {
        HttpSession session = req.getSession(true);
        Storage storage = (Storage) session.getAttribute(Storage.class.getName());
        if (storage == null) {
           storage = new Storage();
           session.setAttribute(Storage.class.getName(), storage);
        }     
        // create odata handler and configure it with CsdlEdmProvider and Processor
        OData odata = OData.newInstance();
        ServiceMetadata edm = odata.createServiceMetadata(new PersonEdmProvider(), new ArrayList<EdmxReference>());
        ODataHttpHandler handler = odata.createHandler(edm);
        handler.register(new PersonEntityCollectionProcessor(storage));
        handler.register(new PersonEntityProcessor(storage));
        handler.register(new PersonPrimitiveProcessor(storage));

        // let the handler do the work
        handler.process(req, resp);
      } catch (RuntimeException e) {
        LOG.error("Server Error occurred in ExampleServlet", e);
        throw new ServletException(e);
      }
    }
}

Storage:

@Stateless
public class Storage {

    @EJB
    PersonDAO psDAO;

    private List<Entity> personList;

    public Storage() {
        personList = new ArrayList<Entity>();
    }

    @PostConstruct
     private void initSampleData(){
         psDAO.getAllPersons();
    }
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="3.1"
    xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
    <servlet>
        <servlet-name>PersonServlet</servlet-name>
        <servlet-class>test.personservice.web.PersonServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>PersonServlet</servlet-name>
        <url-pattern>/PersonService.svc/*</url-pattern>
    </servlet-mapping>

</web-app>
manban
  • 133
  • 1
  • 19

1 Answers1

0

You're creating the Storage instance by yourself, using new, so the Storage object is not managed by the container, so it can't inject the DAO in it. By transition, since the DAO is not null, I can safely guess that the Storage object also creates the DAO using new, so once again, the DAO is not managed by the container, which thus can't inject the entity manager in it.

Use dependency injection. Don't create Storage and the DAO by yourself.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • Thanks for the answer! So all the classes have to be beans and managed by the EJB container, since it's transitive? Does this mean the Servlet has to be a a bean, where I inject the Storage which is also a bean and all the handler, which are registered in the servlet have also to be a bean, since they call the storage class? – manban Jan 11 '17 at 19:41
  • The servlet is already a bean. The container creates it for you. The DAO needs to be a bean, since the container must inject the EM in it. Since you also want to inject the DAO into Storage, Storage must be a bean, and be injected in the servlet. You're manually injecting the Storage into PersonEntityCollectionProcessor, and the other collectors, so they don't need to be beans: nothing must be injected by the container in those objects, and they're not injected anywhere (AFAIK) – JB Nizet Jan 11 '17 at 19:46
  • Ok, now I have a Stateless annotation on the Storage and on the PersonDAO class. I inject the Storage class with an EJB annotation in the Servlet instead of instantiating it by myself. I also inject the PersonDAO in the Storage Class instead of instantiating it manually. But now I get a Nullpointer Exception when I call the getAllPersons() method on the injected personDAO object. It sais: 'EJB Container initialization erro at org.glassfish.ejb.startup.EjbApplication.loadContainers' ... 'Caused by: java.lang.NullPointerException at test.personservice.data.Storage.initSampleData' – manban Jan 11 '17 at 20:38
  • A full description of the error I describe in the comment above can be found here: [link]http://stackoverflow.com/questions/41600590/ejb-bean-injection-nullpointer-exception [link] – manban Jan 12 '17 at 07:03
  • To be able to inject the EM, the container must first create the object. Otherwise, it couldn't inject the EM anywhere. So the constructor is called, then the EM is injected. But you're using the EM in the constructor. So at this point, it's still null. Remove the call to initSampleData() from your constructor. You can annotate the initSampleData() with `@PostConstruct` so that this method is called by the constructor after it has created the bean and injected its dependencies, but I fail to see the point in loading data from a DAO every time your bean is created, and ignoring the result. – JB Nizet Jan 12 '17 at 07:09
  • Thanks! I'll try this later. The functionality is senseless because I just wanted to test if I am able to grab data from my db. When this works, I'll implement real functionality. – manban Jan 12 '17 at 07:52
  • That worked out. Additionally I had to remove the five lines where I set the session attribute 'storage' in the PersonServlet so I don't override the Storage Bean which is injected in the servlet. (Complete answer here: [link]http://stackoverflow.com/questions/41622516/ejb-postconstruct-not-called[link] – manban Jan 12 '17 at 22:25