Jersey (JAX-RS)를 사용하여 Tomcat 컨테이너에 배포 된 간단한 Spring 웹 응용 프로그램을 개발하려고합니다. 엔터티는 JPA와 EclipseLink 공급자를 사용하여 관리되고 MySQL 데이터베이스에 저장됩니다. 나는 EJB를 사용하지 않는다.JPA (EclipseLink)가있는 Spring 프로젝트의 Jersey 컨트롤러에서 EntityManager가 null입니다.
스프링을 통해 EntityManager를 삽입하려고하는데, DB에서 엔터티를 가져 오거나 유지하려고 할 때 EntityManager가 null임을 나타내는 NullPointerException이 발생합니다.
나는 솔루션을 찾기 위해 많은 시간을 보냈으며 자습서와 스레드에서 찾은 모든 코드를 시도했지만 동일한 결과를 얻었다.
프로젝트에 필요한 모든 종속성을 포함 시켰습니다. 필자가 수동으로 EntityManagerFactory를 작성한 다음 getPerson에 EntityManager를 작성하면 작동하지만 올바른 방법이라고 생각하지 않습니다. 또한 서비스를 시작하면 콘솔 루트 출력에서 Spring 루트 WebApplicationContext가 초기화되고 bean 정의가로드되며 영속성 단위 'defaultPU'에 대한 JPA 컨테이너 EntityManagerFactory가 빌드 된 것을 볼 수 있습니다.
나는 분명히 뭔가가 빠졌습니다. 제발이 일을 어떻게 할 수 있습니까? EntityManager가 null이고 PersonController에서 EntityManager를 사용할 수 있도록 삽입하려면 어떻게해야합니까?
Person.java :
package TestSpringApp;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class Person {
@Id
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
PersonController.java :
package TestSpringApp;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
@Component
@Path("/person")
public class PersonController {
@PersistenceContext
EntityManager entityManager;
@GET
@Transactional
public String getPerson() {
Person p = entityManager.find(Person.class, 0);
return p.getName();
}
public void setEntityManager(EntityManager em) {
this.entityManager = em;
}
public EntityManager getEntityManager() {
return this.entityManager;
}
}
beans.xml 환경 :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation=
"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<context:component-scan base-package="TestSpringApp"/>
<tx:annotation-driven />
<context:annotation-config/>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="jpaVendorAdapter" ref="jpaAdapter" />
<property name="persistenceUnitName" value="defaultPU"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="jpaAdapter" class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
<property name="database" value="MYSQL" />
<property name="showSql" value="true" />
</bean>
</beans>
의 persistence.xml :
<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="defaultPU" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>TestSpringApp.Person</class>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/test"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="root"/>
<property name="eclipselink.ddl-generation" value="create-tables" />
<property name="eclipselink.ddl-generation.output-mode" value="database" />
<property name="eclipselink.weaving" value="false"/>
</properties>
</persistence-unit>
</persistence>
,451,515,
의 web.xml :
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:beans.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<display-name>testspring</display-name>
<servlet>
<servlet-name>/</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>TestSpringApp</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>/</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
편집 :
지금까지 내가 생각하는 상황 : 구성 요소 스캔 또는 컨텍스트 : beans.xml 환경에서 주석-설정은 PersonController의 봄을 인식하고 돌보는되었다 이제는 체크를했는데 setEntityManager는 EntityManager 자체 대신 setEntityManager에 @PersistenceContext를두고 @Component를 사용하여 PersonController 클래스에 주석을다는 경우에만 호출된다는 것을 알았습니다. 이렇게하면 setEntityManager가 Spring bean 초기화에 호출되고 그 값이 "Target Factory [org[email protected]15bd577]에 대한 공유 EntityManager 프록시"라는 것을 볼 수 있습니다.
http://localhost:8080/rest/person 요청을 할 때 entityManager.find (Person.class, 0)에서 entityManager가 여전히 null이기 때문에 여전히 문제가 발생합니다.
자습서에서 본 내용 만 알고 있지만 Spring에서 PersonController 클래스를 인식하는 방법은 무엇입니까? NPE를 볼 때 어떻게로드되고 있습니까? – Chris
질문에 대한 원래 게시물의 편집 내용을 참조하십시오. – kolett