PersistenceContext EntityManager注入NullPointerException

我有一个包含以下内容的战争:

META-INF/MANIFEST.MF WEB-INF/classes/META-INF/persistence.xml WEB-INF/classes/com/test/service/TestServlet.class WEB-INF/classes/com/test/service/TestEntity.class WEB-INF/classes/jndi.properties WEB-INF/classes/postgresql-ds.xml WEB-INF/jboss-web.xml WEB-INF/web.xml index.jsp 

persistence.xml中:

 <?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"> <persistence-unit name="test"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <jta-data-source>java:/TestDS</jta-data-source> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/> <property name="hibernate.hbm2ddl.auto" value="update" /> <property name="hibernate.show_sql" value="true" /> </properties> </persistence-unit> </persistence> 

web.xml中:

 <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Test Web Application</display-name> <context-param> <param-name>resteasy.scan</param-name> <param-value>true</param-value> </context-param> <listener> <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class> </listener> <servlet> <servlet-name>Resteasy</servlet-name> <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class> </servlet> <servlet-mapping> <servlet-name>Resteasy</servlet-name> <url-pattern>/service/*</url-pattern> </servlet-mapping> <resource-ref> <res-ref-name>TestDS</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> <res-sharing-scope>Shareable</res-sharing-scope> </resource-ref> </web-app> 

我的TestServlet类如下所示:

 package com.test.service; import java.util.*; import javax.persistence.*; import javax.ws.rs.*; @Path("/service") public class TestService { @PersistenceContext(unitName = "test") private EntityManager em; @GET @Path("/get") @Produces("application/json") public List get() { return em.createQuery("from TestEntity").getResultList(); } } 

当get()方法被调用时,我得到一个NullPointerException; EntityManager尚未被注入。 任何build议,我可能会缺less什么或如何诊断它? 服务器日志中很less。

我敢肯定,我没有jboss-web.xml或web.xml中的数据源条目这个工作。 我已经将ds.xml单独部署到了deploy目录,而且肯定会收到 – 我可以在JMX控制台中看到它。

试过使用JBoss 4.2.3和6.0 build来得到相同的结果。

实体pipe理器只能在事务内部运行的类中注入。 换句话说,它只能被注入到一个EJB中。 其他类必须使用EntityManagerFactory来创build和销毁一个EntityManager。

由于你的TestService不是一个EJB,所以注解@PersistenceContext被忽略。 不仅如此,在JavaEE 5中,无法在JAX-RS服务中注入EntityManager和EntityManagerFactory。 你必须使用JavaEE 6服务器(JBoss 6,Glassfish 3等)。

下面是一个注入EntityManagerFactory的例子:

 package com.test.service; import java.util.*; import javax.persistence.*; import javax.ws.rs.*; @Path("/service") public class TestService { @PersistenceUnit(unitName = "test") private EntityManagerFactory entityManagerFactory; @GET @Path("/get") @Produces("application/json") public List get() { EntityManager entityManager = entityManagerFactory.createEntityManager(); try { return entityManager.createQuery("from TestEntity").getResultList(); } finally { entityManager.close(); } } } 

最简单的方法就是将您的服务声明为EJB 3.1,假设您使用的是JavaEE 6服务器。

相关问题: 将EJB注入到JAX-RS(RESTful服务)

如果组件是一个EJB,那么注入EM就不会有问题。

但是……在JBoss 5中,JAX-RS集成并不好。 如果你有一个EJB,你不能使用扫描,你必须在上下文参数resteasy.jndi.resource中手动列出。 如果您仍然在扫描,Resteasy将扫描资源类并将其注册为vanilla JAX-RS服务并处理生命周期。

这可能是问题所在。