java - 使用 Maven + intelliJ + Tomcat 7 + JPA2 的 EntityManager 上出现 NullpointerException

标签 java maven jpa intellij-idea nullpointerexception

您好,我正在使用 JPA2 设置一个非常简单的应用程序,当我尝试使用 EntityManager 时,出现空指针异常 我在用: 英特尔IDEA 梅文 JPA 2 小服务程序3 Tomcat 7

这是我的项目的结构: -> http://picpaste.com/screen1-ZKITGaeh.jpg

持久性.xml:

<?xml version="1.0" encoding="UTF-8"?>

<persistence-unit name="mymoneyunit" transaction-type="RESOURCE_LOCAL">
    <description>
        Persistence unit for the JPA tutorial of the Hibernate Getting Started Guide
    </description>
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <class>com.mymoney.entities.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/moneydb" />
        <property name="javax.persistence.jdbc.user" value="root" />
        <property name="javax.persistence.jdbc.password" value="****" />

        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
        <property name="hibernate.show_sql" value="true" />
        <property name="hibernate.format_sql" value="true"/>
        <property name="hibernate.hbm2ddl.auto" value="create-drop" />
    </properties>

</persistence-unit>

用户DAO:

package com.mymoney.database;

import com.mymoney.entities.User;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import java.util.List;

public class UserDAO {
    private EntityManager em;
    @PersistenceContext(unitName = "mymoneyunit")
    public void setEntityManager(EntityManager entityManager) {
        this.em = entityManager;
    }
    public List<User> findAll() {

        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<User> criteria = cb.createQuery(User.class);
        Root<User> user = criteria.from(User.class);

        criteria.select(user).orderBy(cb.asc(user.get("name")));
        return em.createQuery(criteria).getResultList();
    }
}

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>myMoney</groupId>
    <artifactId>myMoney-artifact</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>
    <properties>
        <hibernate.version>4.3.8.Final</hibernate.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>
   <!--     <dependency>
            <groupId>javax.enterprise</groupId>
            <artifactId>cdi-api</artifactId>
            <scope>provided</scope>
        </dependency> -->
        <!-- MySQL JDBC connector -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.27</version>
            <scope>provided</scope>
        </dependency>

        <!-- tomcat jdbc -->
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-jdbc</artifactId>
            <version>7.0.35</version>
            <scope>provided</scope>
        </dependency>
        <!-- ******* JPA/Hibernate ******** -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>${hibernate.version}</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate.javax.persistence</groupId>
            <artifactId>hibernate-jpa-2.0-api</artifactId>
            <version>1.0.1.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>${hibernate.version}</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.jboss.weld</groupId>
            <artifactId>weld-core</artifactId>
            <version>2.0.4.Final</version>
            <exclusions>
                <exclusion>
                    <groupId>org.jboss.spec.javax.el</groupId>
                    <artifactId>jboss-el-api_3.0_spec</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

</project>

家庭 Controller :

@WebServlet("/home")
public class HomeController extends javax.servlet.http.HttpServlet {

    protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {

    }

    protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
        System.out.println("doGet");
        UserDAO uDao = new UserDAO();
        List<User> users = uDao.findAll();
        for(User usr : users){
            System.out.println(usr.getEmail());
        }
    }
}

beans.xml

<?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_1_1.xsd"
    bean-discovery-mode="all">
</beans>

异常(exception):

java.lang.NullPointerException
    com.mymoney.database.UserDAO.findAll(UserDAO.java:25)
    com.mymoney.controllers.HomeController.doGet(HomeController.java:28)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)

没有任何内容被写入与 JPA 设置相关的日志:(。

感谢您的帮助

更新

我将 persistence.xml 移至 resources/META-INF 内 创建了一个新类来管理实体管理器,而不是使用注释来注入(inject)实体管理器:

public class PersistenceManager {
    private static PersistenceManager INSTANCE;
    private EntityManagerFactory emFactory;

    public static PersistenceManager getInstance(){
        if(PersistenceManager.INSTANCE == null){
            PersistenceManager.INSTANCE = new PersistenceManager();
        }    
        return PersistenceManager.INSTANCE;
    }

    private PersistenceManager() {
        emFactory = Persistence.createEntityManagerFactory("mymoneyunit");
    }

    public EntityManager getEntityManager() {
        return emFactory.createEntityManager();
    }


    public void close() {
        emFactory.close();
    }
}

现在我得到: 导致:java.lang.ClassNotFoundException:无法加载请求的类:com.mysql.jdbc.Driver

修复了上述问题,检查intellij中要导出的mysql jar并更改其在类路径中的顺序。

最佳答案

看不见的违规代码就在这里:

private EntityManager em;
    @PersistenceContext(unitName = "mymoneyunit")
    public void setEntityManager(EntityManager entityManager) {
        this.em = entityManager;
    }
    ...
}

在上面的代码中,容器不会将 EntityManager 注入(inject)到您的 UserDAO 类中,因为:

1). @PersistenceContext 注释可用于任何 CDI bean、EJB 或 JSF ManagedBean。

2).这个特定的 EntityManager 作为 EXTENDED 持久性上下文注入(inject),这仅仅意味着 EntityManager 在创建 @Stateful bean 时创建,并在 @Stateful bean 销毁时销毁。

简单地说,EntityManager 中的数据在 @Stateful bean 的生命周期内进行缓存。

EXTENDED持久化上下文的使用仅适用于@Stateful bean。

所以,把这个:

@Stateful
public class UserDAO {
    private EntityManager em;
    @PersistenceContext(unitName = "mymoneyunit")
    public void setEntityManager(EntityManager entityManager) {
        this.em = entityManager;
    }
    ....
}

现在,容器将注入(inject)名为 mymoneyunitEntityManager

注意:为了使用 JavaEE 依赖注入(inject),您需要使用 CDI 实现之一,例如 JBoss Weld(在这种情况下,您需要配置如何将 JBoss Weld 与 Tomcat 一起使用)或由 TomEE 提供。

关于java - 使用 Maven + intelliJ + Tomcat 7 + JPA2 的 EntityManager 上出现 NullpointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28594581/

相关文章:

java - Java中编辑距离: How arrange the code?

java - Liferay 公告 portlet Hook

java - 在替换密码 Java 中保留空格和标点符号

java - 将 EntityManager 与数据库同步

java - 同时按下按键时未接收到按键事件

java - 在heroku上部署项目时如何修复maven插件和java版本错误?

java - Spring Boot 和 Junit 的 Maven 依赖

eclipse - 在 Eclipse 中使用 Jetty Maven 插件在多模块项目 : Compilation unit not on the build path 上进行调试

java - 从父实体中删除时,Spring data JPA @PreRemove ConcurrentModificationException

spring - 带有 Java util.Date 的 Postgres 时间戳列