I am working on Java Web Application with JSP, Servlet, EJB, JDBC, Tomcat, and PostgreSQL, by using Intellij.
I am trying to inject my CustomerDAO.java into SignUp.java (Servlet), but it always returns NullPointerException, which is shown below. I hope someone can tell me what I have did wrong. Thank you in advance!
Message:
Cannot invoke "dao.CustomerDAO.createCustomer(model.Customer)" because "this.customerDAO" is null
Exception:
java.lang.NullPointerException: Cannot invoke "dao.CustomerDAO.createCustomer(model.Customer)" because "this.customerDAO" is null
controller.SignUp.doPost(SignUp.java:24)
jakarta.servlet.http.HttpServlet.service(HttpServlet.java:563)
jakarta.servlet.http.HttpServlet.service(HttpServlet.java:631)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Below are my files to work around.
JpaEntityManagerFactory.java
package util;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;
public class JpaEntityManagerFactory {
private static final String PERSISTENCE_UNIT_NAME = "postgres";
private static EntityManagerFactory emFactory;
public static EntityManager getEntityManager() {
if (emFactory == null || !emFactory.isOpen()) {
emFactory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
}
return emFactory.createEntityManager();
}
public static void closeEntityManagerFactory() {
if (emFactory != null && emFactory.isOpen()) {
emFactory.close();
}
}
}
AbstractFacade.java
package dao;
import jakarta.persistence.EntityManager;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Root;
import util.JpaEntityManagerFactory;
import java.util.List;
public abstract class AbstractFacade<T> {
private EntityManager em = JpaEntityManagerFactory.getEntityManager();
private Class<T> entityClass;
public AbstractFacade(Class<T> entityClass) {
this.entityClass = entityClass;
}
public void create(T entity) {
em.getTransaction().begin();
em.persist(entity);
em.getTransaction().commit();
}
CustomerDAO.java
@Stateless
public class CustomerDAO extends AbstractFacade<Customer> implements CustomerDAOI {
public CustomerDAO() {
super(Customer.class);
}
public boolean createCustomer(Customer customer){
try{
this.create(customer);
return true;
}
catch (Exception e){
return false;
}
}
SignUp.java
package controller;
import jakarta.ejb.EJB;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import dao.CustomerDAO;
import model.Customer;
import java.io.IOException;
@WebServlet(name = "SignUp", value = "/SignUp")
public class SignUp extends HttpServlet {
@EJB
private CustomerDAO customerDAO;
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
Customer customer = new Customer("John");
customerDAO.createCustomer(customer); //returns NullPointerException
}
}
Everything only works if I changed this
@EJB
private CustomerDAO customerDAO;
to
@EJB
private CustomerDAO customerDAO = new CustomerDAO();
but this is not I want, as I have to apply EJB in my application.
Installed Jakarta EE EJB Plugin in Intellij.
customerDAO in private CustomerDAO customerDAO
once to be greyed out and appear Private field 'customerDAO' is never assigned
, and this step recovers it.
Used @ManagedBean and mappedName in SignUp.java
@WebServlet(name = "SignUp", value = "/SignUp")
@ManagedBean
public class SignUp extends HttpServlet {
@EJB(mappedName = "CustomerDAO")
private CustomerDAO customerDAO;
Used @Local for CustomerDAOI.java.
Added this into src/main/webapp/WEB-INF/web.xml
<ejb-local-ref>
<ejb-ref-name>CustomerDAO</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<local>dao.CustomerDAO</local>
</ejb-local-ref>
Tomcat doesnt support EJB, it is just a web container. Use compliant Jakarta EE server like OpenLiberty