使用 Maven + intelliJ + Tomcat 7 + JPA2 在 EntityManager 上出现 NullpointerException
NullpointerException on EntityManager using Maven + intelliJ + Tomcat 7 + JPA2
您好,我正在使用 JPA2 设置一个非常简单的应用程序,当我尝试使用 EntityManager 时出现空指针异常
我在用:
智能想法
行家
联合行动计划 2
小服务程序 3
Tomcat7
这是我的项目结构:
-> 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>
家庭控制器:
@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 设置相关的日志:(。
感谢您的帮助
更新
我把 persistence.xml 移到了 resources/META-INF
创建了一个新的 class 来管理实体管理器,而不是使用注解来注入实体管理器:
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:无法加载请求 class:com.mysql.jdbc.Driver
修复了上面的问题,在intellij中检查要导出的mysql jar并更改它在class路径中的顺序。
Unseen 违规代码位于此处:
private EntityManager em;
@PersistenceContext(unitName = "mymoneyunit")
public void setEntityManager(EntityManager entityManager) {
this.em = entityManager;
}
...
}
在上面的代码中,容器不会将 EntityManager 注入到您的 UserDAO class 因为:
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;
}
....
}
现在您的 EntityManager 名称为 mymoneyunit 将由容器注入。
注意: 为了使用 JavaEE 依赖注入,您需要使用一种 CDI 实现,例如 JBoss Weld(在这种情况下,您需要配置为如何使用 JBoss Weld with Tomcat)或由 TomEE.
提供
您好,我正在使用 JPA2 设置一个非常简单的应用程序,当我尝试使用 EntityManager 时出现空指针异常 我在用: 智能想法 行家 联合行动计划 2 小服务程序 3 Tomcat7
这是我的项目结构: -> 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>
家庭控制器:
@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 设置相关的日志:(。
感谢您的帮助
更新
我把 persistence.xml 移到了 resources/META-INF 创建了一个新的 class 来管理实体管理器,而不是使用注解来注入实体管理器:
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:无法加载请求 class:com.mysql.jdbc.Driver
修复了上面的问题,在intellij中检查要导出的mysql jar并更改它在class路径中的顺序。
Unseen 违规代码位于此处:
private EntityManager em;
@PersistenceContext(unitName = "mymoneyunit")
public void setEntityManager(EntityManager entityManager) {
this.em = entityManager;
}
...
}
在上面的代码中,容器不会将 EntityManager 注入到您的 UserDAO class 因为:
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;
}
....
}
现在您的 EntityManager 名称为 mymoneyunit 将由容器注入。
注意: 为了使用 JavaEE 依赖注入,您需要使用一种 CDI 实现,例如 JBoss Weld(在这种情况下,您需要配置为如何使用 JBoss Weld with Tomcat)或由 TomEE.
提供