使用Maven + intelliJ + Tomcat 7 + JPA2在EntityManager上进行NullpointerException

时间:2015-02-18 21:47:58

标签: java maven jpa intellij-idea nullpointerexception

您好我正在使用JPA2设置一个非常简单的应用程序,当我尝试使用EntityManager时,我得到一个nullpointer异常 我在用: intellij IDEA Maven的 JPA 2 Servlet 3 Tomcat 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>

UserDAO的:

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>

HomeController中:

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

感谢您的帮助

更新

我在资源/ META-INF中移动了persistence.xml 创建了一个新类来管理entitymanager而不是使用注释来注入entitymanager:

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并在类路径中更改它的顺序。

1 个答案:

答案 0 :(得分:0)

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

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 持久性上下文注入的,这意味着 @Stateful EntityManager >销毁 @Stateful bean时创建并销毁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;
    }
    ....
}

现在,容器会注入名称为 mymoneyunit EntityManager

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