您好我正在使用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并在类路径中更改它的顺序。
答案 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 提供。