You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tomcat中用EntityManager持久化对象遇DAO空指针及驱动问题求助

Tomcat中使用EntityManager持久化User对象的两类问题及解决方法

问题1:Servlet中@Inject注入的UserDao为空,触发NullPointerException

相关代码

User.java

package ma.ac.iga.jee_with_spring.entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class User {
    @Id
    @GeneratedValue (strategy = GenerationType.IDENTITY)
    private int id;
    private String firstName;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
}

UserServlet.java

package ma.ac.iga.jee_with_spring.servlet;

import ma.ac.iga.jee_with_spring.dao.UserDao;
import ma.ac.iga.jee_with_spring.entity.User;

import javax.inject.Inject;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/user")
public class UserServlet extends HttpServlet {

    @Inject
    UserDao userDao; // 注入实例为空,触发空指针

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        User user = new User();
        user.setFirstName("achraf");
        userDao.save(user);
    }
}

UserDao.java

package ma.ac.iga.jee_with_spring.dao;

import ma.ac.iga.jee_with_spring.entity.User;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

// 看到有些示例用@Stateless,但这里无法引用

public class UserDao {
    @PersistenceContext(unitName = "default")
    private EntityManager entityManager;

    public void save(User user) {
        entityManager.persist(user);
    }
}

persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
    <persistence-unit name="default">

        <class>ma.ac.iga.jee_with_spring.entity.User</class>

        <properties>
            <property name="javax.persistence.jdbc.Driver" value="com.mysql.jdbc.Driver"/>
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/projetjee"/>
            <property name="javax.persistence.jdbc.user" value="root"/>
            <property name="javax.persistence.jdbc.password" value="1341"/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL8Dialect"/>
            <property name="hibernate.hbm2ddl.auto" value="create"/>
        </properties>

    </persistence-unit>
</persistence>

pom.xml(关键依赖部分)

<dependencies>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>4.0.1</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>5.6.15.Final</version>
    </dependency>
    <dependency>
        <groupId>org.jboss.weld.se</groupId>
        <artifactId>weld-se-core</artifactId>
        <version>3.1.9.Final</version>
    </dependency>
    <!-- 其他依赖省略 -->
</dependencies>

错误信息

Type Exception Report

Message Cannot invoke "ma.ac.iga.jee_with_spring.dao.UserDao.save(ma.ac.iga.jee_with_spring.entity.User)" because "this.userDao" is null

Description The server encountered an unexpected condition that prevented it from fulfilling the request.

Exception

java.lang.NullPointerException: Cannot invoke "ma.ac.iga.jee_with_spring.dao.UserDao.save(ma.ac.iga.jee_with_spring.entity.User)" because "this.userDao" is null
    ma.ac.iga.jee_with_spring.servlet.UserServlet.doPost(UserServlet.java:24)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:555)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:623)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)

解决方法

  1. 为UserDao添加CDI管理注解
    CDI容器只会管理带有特定注解的类,给UserDao添加@ApplicationScoped或@Named注解,让它成为可被注入的CDI Bean:
import javax.enterprise.context.ApplicationScoped;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@ApplicationScoped
public class UserDao {
    @PersistenceContext(unitName = "default")
    private EntityManager entityManager;

    public void save(User user) {
        entityManager.persist(user);
    }
}
  1. 替换CDI依赖为Servlet环境适配包
    当前使用的weld-se-core是SE环境的CDI实现,Tomcat作为Servlet容器需要适配的weld-servlet-core,修改pom.xml中的依赖:
<dependency>
    <groupId>org.jboss.weld.servlet</groupId>
    <artifactId>weld-servlet-core</artifactId>
    <version>3.1.9.Final</version>
</dependency>

同时移除原有的weld-se-core依赖。

  1. 添加beans.xml文件
    在WEB-INF目录下创建beans.xml文件,告知CDI容器启动并扫描Bean:
<?xml version="1.0" encoding="UTF-8"?>
<beans 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/beans_2_0.xsd"
       version="2.0" bean-discovery-mode="all">
</beans>

bean-discovery-mode="all"会扫描项目中所有带CDI注解的类。


问题2:Servlet中直接创建EntityManagerFactory提示"no suitable driver for mysql"

相关代码

EntityManagerFactory emf = Persistence.createEntityManagerFactory("default");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
User user = new User();
user.setFirstName("achraf");
em.persist(user);
em.getTransaction().commit();

解决方法

  1. 添加MySQL JDBC驱动依赖
    pom.xml中缺少MySQL驱动,添加以下依赖:
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.33</version>
    <scope>runtime</scope>
</dependency>

如果使用MySQL 8.0+版本,需同步修改persistence.xml中的驱动类名和URL(添加时区参数避免时区错误):

<property name="javax.persistence.jdbc.Driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/projetjee?serverTimezone=UTC"/>
  1. 确保驱动被打包到WAR中
    检查maven-war-plugin配置,确认依赖被正确打包到WAR的WEB-INF/lib目录下,默认配置会自动打包,若有特殊配置需手动验证。

内容的提问来源于stack exchange,提问作者achraf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 17:17:31