2016-10-13 4 views
0

Я делаю проект GWTP и использую Spring Data JPA для подключения к базе данных оракула. Я прочитал несколько руководств, в которых интерфейс репозитория используется напрямую без использования реализации. Это было @Autowired там, где это было необходимо, и это работало нормально. Я попытался использовать ту же стратегию, но кажется, что @Autowired аннотация не работает вообще.@Autowired не вводит Spring Data JPA Repository - NullPointerException

Вот мой Repository:

@Repository 
public interface BugRepository extends JpaRepository<Bug, Long> { 
    List<Bug> findAll(); 
..... 
} 

Я пытаюсь внедрить его с @Autowired в моей реализации услуг (я использую RESTful услуги):

@Produces(MediaType.APPLICATION_JSON) 
@Consumes(MediaType.APPLICATION_JSON) 
@Path("/bugs") 
@Component 
public class BugServiceImpl{ 
    @Autowired 
    private BugRepository bugRepository; 

    @GET 
    @Path("/findAll") 
    public List<Bug> findAll() { 
    return bugRepository.findAll(); 
    } 
} 

Вот мой Entity:

@Entity 
@Table(name = "BUGS") 
@SequenceGenerator(name = "BUG_SEQUENCE", sequenceName = "BUG_SEQUENCE") 
public class Bug implements Serializable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "BUG_SEQUENCE") 
    @Column(name="BUG_ID") 
    private Long bugId; 

    @Column(name="BUG_NAME") 
    private String bugName; 

    @OneToOne 
    @PrimaryKeyJoinColumn 
    @Column(name="CREATED_BY") 
    private User createdBy; 

    @OneToOne 
    @PrimaryKeyJoinColumn 
    @Column(name="ASSIGNED_TO") 
    private User assignedTo; 

    @Column(name="CREATION_DATE") 
    private Date creationDate; 

    @Column(name="LAST_UPDATE_DATE") 
    private Date lastUpdateDate; 

    @Column(name="BUG_COMMENT") 
    private String bugComment; 

    @OneToOne(cascade = CascadeType.ALL, optional = false, fetch = FetchType.EAGER, orphanRemoval = true) 
    @PrimaryKeyJoinColumn 
    @Column(name="PRIORITY_ID") 
    private Priority priority; 

    @OneToOne 
    @PrimaryKeyJoinColumn 
    private Status status; 

    public Bug() { 
    } 
} 

У меня также есть applicationContext.xml и persistence.xml в основном/ресурсы/META-INF. Вот мой applicationContext.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" 
    xmlns:jpa="http://www.springframework.org/schema/data/jpa" 
    xmlns:jdbc="http://www.springframework.org/schema/jdbc" 
    xmlns:p="http://www.springframework.org/schema/p" 

    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.0.xsd 
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx-3.1.xsd 
    http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd 
    http://www.springframework.org/schema/data/jpa 
    http://www.springframework.org/schema/data/jpa/spring-jpa-1.0.xsd 
    http://www.springframework.org/schema/jdbc 
    http://www.springframework.org/schema/jdbc/spring-jdbc.xsd"> 

<context:component-scan base-package="com.edu" /> 

<jpa:repositories base-package="com.edu.server.repositories" /> 

<context:annotation-config /> 

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
    <property name="driverClassName" value="oracle.jdbc.OracleDriver" /> 
    <property name="url" value="***"/> 
    <property name="username" value="***"/> 
    <property name="password" value="***"/> 
</bean> 

<!-- EntityManagerFactory --> 
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" 
     p:packagesToScan="com.edu.shared.entity" 
     p:dataSource-ref="dataSource" 
> 
    <property name="jpaVendorAdapter"> 
     <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
      <property name="generateDdl" value="true" /> 
      <property name="showSql" value="false" /> 
     </bean> 
    </property> 
</bean> 

<tx:annotation-driven transaction-manager="transactionManager" /> 

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
    <property name="entityManagerFactory" ref="entityManagerFactory" /> 
</bean> 

Мой 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_2_0.xsd" 
     version="2.0"> 

<!-- oracle --> 

<persistence-unit name="oracle"> 
    <provider>org.hibernate.ejb.HibernatePersistence</provider> 

    <class>com.edu.server.service.BugServiceImpl</class> 
    <class>com.edu.server.repositories.BugRepository</class> 
    <class>com.edu.shared.entity.Bug</class> 

    <properties> 
     <property name="hibernate.archive.autodetection" value="class" /> 
     <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" /> 
     <property name="hibernate.connection.driver_class" value="oracle.jdbc.OracleDriver" /> 
     <property name="hibernate.connection.url" value="***" /> 
     <property name="hibernate.connection.username" value="***" /> 
     <property name="hibernate.connection.password" value="***" /> 
     <property name="hibernate.flushMode" value="FLUSH_AUTO" /> 
     <property name="hibernate.hbm2ddl.auto" value="update" /> 
    </properties> 
</persistence-unit> 

И, наконец, исключение, которое я получаю:

java.lang.NullPointerException 
com.edu.server.service.BugServiceImpl.findAll(BugServiceImpl.java:39) 
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
java.lang.reflect.Method.invoke(Method.java:606) 
... 

Когда Я отлаживаю e и помещает точку останова в автообновленный репозиторий, он кажется нулевым, поэтому я полагаю, что он не был введен правильно, и поэтому при вызове метода findAll запускается исключение NullPointerException. Итак, почему вы думаете, что @Autowired аннотация не работает?

+0

Пакет всех классов (аннотированные классы с Component, Service, Repository) начинается с com.edu? – Unknown

+0

Becuase это не управляемый весом компонент, но управляемый Джерси, поэтому '@ Autowired' ничего не делает. Поле '@ Autowired' не может быть« null », если зависимость не может быть выполнена, приложение будет разбиваться при запуске (оно не запустится), а не во время выполнения. Когда это «нуль», вы сами создаете экземпляры классов (например, «новый BugServiceImpl»), или yu используют его за пределами Spring (это то, что вы делаете). Настройка Джерси и весна, чтобы правильно интегрироваться, как это сделать, ясно объяснено в справочнике по джерси. –

+0

В вашем persistance.xml у вас должны быть только сущности beans (например, Bug), но не Сервисы или Repos (у вас есть ваш репо там, где есть ваш ServiceImpl) – Mechkov

ответ

0

Я думаю, что вы смешиваете два способа настройки Spring/JPA. В прошлый раз, когда я сконфигурировал проект Spring/JPA с XML, я использую только DataSource bean без конфигурации persistence.xml для подключения к базе данных. Я могу предложить вам прочитать официальную документацию Spring Data. Сообщество имеет одну из лучших документов.

http://docs.spring.io/spring/docs/current/spring-framework-reference/html/orm.html

0

Первая проблема, что я вижу, как вы аннотированный свой интерфейс с @Repository

Вы не должны делать это, но следующим образом:

//no annotation here 
public interface BugRepository extends JpaRepository<Bug, Long> { 
    List<Bug> findAll(); 
..... 
} 

Во-вторых, убедитесь, что ваш интерфейс BugRepository находится в нижеследующем пакете, иначе он не будет работать:

<jpa:repositories base-package="com.edu.server.repositories" /> 

Третьей вещи я заметил в вашем persistance.xml, вы отметили не только @Entity бобов, но @Service и @Repository.Вы должны только @Entity бобов (которые должны управляться)

Наконец, вы, кажется, смешивание Spring и Jersey, поэтому убедитесь, что у вас есть Spring контейнер (приложение/веб-контекст) правильно настроены, поэтому он может управлять (вставлять) ваши бобы/репо/сервисы.

0

Я хочу поблагодарить всех за помощь. Я решил свою проблему. В конфигурационных файлах были проблемы.

Прежде всего, я действительно не нужна persistence.xml, потому что я создал DataSource компонента в моем applicationContext.xml, который содержит все необходимую информацию относительно соединения с моей базой данных. Полагаю, вы не должны смешивать обе вещи.

Во-вторых,, вы должны правильно настроить связь между весной и Джерси. Мне пришлось добавить некоторые новые зависимости в моем pom.xml, которые были необходимы для связывания Spring и Jersey (есть зависимость jersey-spring3, о которой я не знал). Итак, теперь все зависимости, которые я использую, относительно Spring и Джерси, таковы:

 <dependency> 
      <groupId>javax.ws.rs</groupId> 
      <artifactId>javax.ws.rs-api</artifactId> 
      <version>${javax.rs.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.glassfish.jersey.containers</groupId> 
      <artifactId>jersey-container-servlet</artifactId> 
      <version>${jersey.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.glassfish.jersey.core</groupId> 
      <artifactId>jersey-server</artifactId> 
      <version>${jersey.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.glassfish.jersey.media</groupId> 
      <artifactId>jersey-media-json-jackson</artifactId> 
      <version>${jersey.version}</version> 
     </dependency> 

     <dependency> 
      <groupId>org.fusesource.restygwt</groupId> 
      <artifactId>restygwt</artifactId> 
      <version>1.4</version> 
     </dependency> 

     <dependency> 
      <groupId>io.spring.platform</groupId> 
      <artifactId>platform-bom</artifactId> 
      <version>1.1.2.RELEASE</version> 
      <type>pom</type> 
      <!--<scope>import</scope>--> 
      <scope>compile</scope> 
     </dependency> 

     <!-- DataSource (HikariCP) --> 
     <dependency> 
      <groupId>com.zaxxer</groupId> 
      <artifactId>HikariCP</artifactId> 
      <version>2.2.5</version> 
     </dependency> 

     <!-- JPA Provider (Hibernate) --> 
     <dependency> 
      <groupId>org.hibernate</groupId> 
      <artifactId>hibernate-entitymanager</artifactId> 
      <version>4.3.8.Final</version> 
     </dependency> 

     <dependency> 
      <groupId>org.springframework.data</groupId> 
      <artifactId>spring-data-jpa</artifactId> 
      <version>1.10.2.RELEASE</version> 
     </dependency> 

     <dependency> 
      <groupId>com.oracle</groupId> 
      <artifactId>ojdbc6</artifactId> 
      <version>12.1.0.2</version> 
     </dependency> 

     <dependency> 
      <groupId>org.hibernate</groupId> 
      <artifactId>hibernate-core</artifactId> 
      <version>4.3.8.Final</version> 
     </dependency> 

     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-context</artifactId> 
      <version>${spring.version}</version> 
     </dependency> 

    <dependency> 
     <groupId>org.springframework</groupId> 
     <artifactId>spring-beans</artifactId> 
     <version>${spring.version}</version> 
    </dependency> 

    <dependency> 
     <groupId>org.springframework</groupId> 
     <artifactId>spring-core</artifactId> 
     <version>${spring.version}</version> 
    </dependency> 

    <dependency> 
     <groupId>org.springframework</groupId> 
     <artifactId>spring-orm</artifactId> 
     <version>${spring.version}</version> 
    </dependency> 

    <dependency> 
     <groupId>org.springframework</groupId> 
     <artifactId>spring-web</artifactId> 
     <version>${spring.version}</version> 
    </dependency> 

    <dependency> 
     <groupId>org.glassfish.jersey.ext</groupId> 
     <artifactId>jersey-spring3</artifactId> 
     <version>${jersey.version}</version> 
     <exclusions> 
      <exclusion> 
       <groupId>org.springframework</groupId> 
       <artifactId>spring-core</artifactId> 
      </exclusion> 
      <exclusion> 
      <groupId>org.springframework</groupId> 
       <artifactId>spring-web</artifactId> 
      </exclusion> 
      <exclusion> 
       <groupId>org.springframework</groupId> 
       <artifactId>spring-beans</artifactId> 
      </exclusion> 
     </exclusions> 
    </dependency> 

Кроме того, я должен был настроить мой web.xml так, чтобы Джерси мог читать applicationContext.xml. Без настройки моего web.xml applicationContext.xml был бесполезен, поэтому аннотации и соединение с базой данных не работали. Вот моя web.xml:

<?xml version="1.0" encoding="UTF-8"?> 
    <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_2_5.xsd" 
      version="2.5"> 

     <listener> 
     <listener-class> 
      org.springframework.web.context.ContextLoaderListener 
     </listener-class> 
     </listener> 

     <welcome-file-list> 
     <welcome-file>index.html</welcome-file> 
     </welcome-file-list> 

     <context-param> 
      <param-name>contextConfigLocation</param-name> 
      <param-value>classpath:META-INF/applicationContext.xml</param-value> 
     </context-param> 

     <servlet> 
      <servlet-name>jersey-serlvet</servlet-name> 
      <servlet-class> 
      org.glassfish.jersey.servlet.ServletContainer 
      </servlet-class> 
     <init-param> 
      <param-name>jersey.config.server.provider.packages</param-name> 
      <param-value>com.edu</param-value> 
     </init-param> 
     <load-on-startup>1</load-on-startup> 
     </servlet> 

     <servlet-mapping> 
      <servlet-name>jersey-serlvet</servlet-name> 
      <url-pattern>/rest/*</url-pattern> 
     </servlet-mapping> 
    </web-app> 

Насколько я понял ContextLoadListener убеждается веб-конфигурации «прослушивает» для других файлов конфигурации XML, и это как applicationContext.xml теперь читать и используется. И с этими настройками

<param-name>jersey.config.server.provider.packages</param-name> 
     <param-value>com.edu</param-value> 

Я убеждаюсь, что мои пакеты будут проверяться на @Provider и @Path аннотации и без них куска моего кода моих услуги не будут активными. Подробнее об этой настройке Provider пакетов можно прочитать здесь:

https://jersey.java.net/apidocs/2.23.2/jersey/org/glassfish/jersey/server/ServerProperties.html#PROVIDER_PACKAGES

Я надеюсь, что мой вопрос, и этот ответ полезен для все с подобными проблемами конфигурации.

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