2011-01-16 2 views
38

У меня есть война, содержащий следующее: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 не был введен. Любые предложения о том, что я могу потерять, или как я могу его диагностировать? В журнале сервера очень мало.

Уверен, что это работало без jboss-web.xml или записи источника данных в web.xml. Я также разложил ds.xml в каталог развертывания, и это определенно подобрано - я вижу его в консоли JMX.

Пробовал использовать JBoss 4.2.3 и версию 6.0 с тем же результатом.

+0

Угадайте, есть ли проблемы с публикацией XML в разделах кода ?! – rich

+0

Вам нужно было бы избежать < and > -> < и > – adrianboimvaser

+3

Я никогда не пробовал это на практике, поэтому не связывайте меня с этим, но действительно ли возможно запустить JPA на webapp, который был объявлен запущенным как Servlet 2.3 (J2EE 1.3) вместо Servlet 2.5 (Java EE 5, когда JPA была введена в первый раз)? – BalusC

ответ

70

Администратор сущности может вводиться только в классы, выполняемые внутри транзакции. Другими словами, его можно вводить только в EJB. Другой класс должен использовать EntityManagerFactory для создания и уничтожения EntityManager.

Поскольку ваш TestService не является EJB, аннотация @PersistenceContext просто игнорируется. Кроме того, в JavaEE 5 невозможно внедрить EntityManager или EntityManagerFactory в службу JAX-RS. Вы должны пойти с сервером 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.

Связанный вопрос: Inject an EJB into JAX-RS (RESTful service)

+1

Спасибо, аналогичная проблема, хотя в том, что я получаю NPE на этой строке:

 EntityManager entityManager = entityManagerFactory.createEntityManager(); 
rich

+0

Спасибо, это сработало для меня! Я использую CXF 2.7.5, Hibernate 4.x, Spring 3.x и JPA 2.x. –

+0

Пожалуйста, дайте мне понять, почему я не могу ввести менеджера сущностей в бранды без состояния @PersistenceContext (unitName = "Tester2PU") private EntityManager em; в tomcat 7.0.27 - null. спасибо senthil – user1503117

2

Если компонент является EJB, то есть не должна быть проблемой нагнетания EM.

Но .... В JBoss 5 интеграция JAX-RS невелика. Если у вас есть EJB, вы не можете использовать сканирование, и вы должны вручную перечислить его в контексте-param resteasy.jndi.resource. Если вы все еще сканируете, Resteasy сканирует класс ресурсов и регистрирует его как службу ванильного JAX-RS и обрабатывает жизненный цикл.

Возможно, это проблема.

Смежные вопросы