【问题标题】:NullpointerException on EntityManager using Maven + intelliJ + Tomcat 7 + JPA2EntityManager 上的 NullpointerException 使用 Maven + intelliJ + Tomcat 7 + JPA2
【发布时间】:2015-04-20 02:26:11
【问题描述】:

您好,我正在使用 JPA2 设置一个非常简单的应用程序,当我尝试使用 EntityManager 时出现空指针异常 我在用: 智能理念 马文 JPA 2 小服务程序 3 雄猫 7

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

Persistence.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>

家庭控制器:

@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>

例外:

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 设置相关的日志:(.

感谢您的帮助

更新

我在 resources/META-INF 中移动了 persistence.xml 创建了一个新类来管理实体管理器,而不是使用注解来注入实体管理器:

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,并在classpath中改变它的顺序。

【问题讨论】:

  • 显示 HomeController 的代码。它如何获得对 dao 的引用?
  • 还有 beans.xml。你的 pom 不相关。
  • 我编辑了问题并添加了您询问的详细信息.. 谢谢

标签: java maven jpa intellij-idea nullpointerexception


【解决方案1】:

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

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

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

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

2)。这个特殊的 EntityManager 是作为 EXTENDED 持久化上下文注入的,这意味着 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;
    }
    ....
}

现在您的名为 mymoneyunitEntityManager 将被容器注入。

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

【讨论】:

  • 这个解决方案迫使我使用我不想要的 EJB 女巫。也许我不能像我尝试过的那样使用依赖注入。我更改了实现以使用单例类创建 EntityManager。它起作用了,至少我开始遇到另一个异常:org.hibernate.boot.registry.classloading.spi.ClassLoadingException: Unable to load class [com.mysql.jdbc.Driver]
  • 这意味着 Hibernate 无法从您的 MySQL JDBC Driver JAR 中找到 Driver 类。您能否提供新的 StackTrace 来代替旧的。
  • 我发现了问题。我不得不更改列表中 mysql 驱动程序的顺序并检查以导出它.. 修复了。
  • @RodrigoDeOliveiraMurta 很高兴你明白了。对 IntelliJ 没有任何经验 - :)
  • @RodrigoDeOliveiraMurta 也可能是因为您的 mysql 依赖范围是“提供的”,在运行时不可用。将其更改为可在所有构建类路径中使用的“编译”范围
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-30
  • 2012-04-29
  • 1970-01-01
  • 1970-01-01
  • 2016-09-04
  • 2017-02-03
  • 1970-01-01
相关资源
最近更新 更多