【问题标题】:@Autowired does not inject Spring Data JPA Repository - NullPointerException@Autowired 不注入 Spring Data JPA Repository - NullPointerException
【发布时间】:2016-10-13 12:27:22
【问题描述】:

我正在做一个 GWTP 项目,并使用 Spring Data JPA 与 oracle 数据库进行连接。我已经阅读了几个教程,其中直接使用存储库接口而不使用实现。在需要的地方是@Autowired,它工作得很好。我尝试使用相同的策略,但似乎 @Autowired 注释根本不起作用。

这是我的存储库:

@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
@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() {
   }
}

我在 main/resources/META-INF 中也有 applicationContext.xml 和 persistence.xml。这是我的 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)
...

当我调试代码并向自动装配的存储库放置断点时,它似乎为空,所以我认为它没有正确注入,这就是调用 findAll 方法会触发 NullPointerException 的原因。那么,为什么您认为@Autowired 注释不起作用?

【问题讨论】:

  • 所有类(带有Component、Service、Repository的注解类)的包都以com.edu开头?
  • 因为它不是 Spring 管理的 bean,而是由 Jersey 管理,因此 @Autowired 没有做任何事情。 @Autowired 字段不能是 null 如果无法满足依赖项,您的应用程序将在启动时中断(它不会启动)而不是在执行期间。 null 什么时候是您自己创建类的实例(即new BugServiceImpl),或者您在 Spring 范围之外使用它(这就是您所做的)。设置球衣和弹簧以正确集成,球衣参考指南中明确说明了如何完成。
  • 在您的persistance.xml 中,您应该只有实体bean(如Bug),但没有Services 或Repos(您有您的Repo,还有您的ServiceImpl)
  • 你是如何部署你的服务的? BugServiceImpl 是如何以及在哪里调用的?如果你让 Jersey 实例化它,那么它不会被视为 Spring bean,自动装配将不起作用。
  • 未知 - 是的,所有的包都是这样开始的。 @M.Deinum 我会阅读本指南。谢谢!我实际上使用了一个链接到 BugServiceImpl 的异步接口,所以我使用接口调用我的服务方法并且我不创建任何实例。

标签: java spring repository spring-data-jpa autowired


【解决方案1】:

我认为您正在混合使用两种 Spring/JPA 配置方式。上次当我使用 XML 配置 Spring/JPA 项目时,我只使用 DataSource bean 没有 persistence.xml 配置来连接到数据库。我可以建议你阅读 Spring Data 的官方文档。社区拥有最好的文档之一。

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

【讨论】:

    【解决方案2】:

    第一个我看到的问题是你用@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 bean,还注意到@Service@Repository。你应该只有@Entity bean(要管理)

    最后,您似乎在混合使用 SpringJersey,因此请确保正确设置了 Spring 容器(应用程序/Web 上下文),以便它可以管理(注入)你的 bean/repos/services。

    【讨论】:

      【解决方案3】:

      我要感谢大家的帮助。我解决了我的问题。我的配置文件有问题。

      首先,我真的不需要任何persistence.xml,因为我在applicationContext.xml 中创建了一个dataSource bean,其中包含有关与我的数据库连接的所有所需信息.我想你不应该把这两种东西混在一起。

      其次,您应该正确配置Spring和Jersey之间的链接。我必须在我的 pom.xml 中添加一些新的依赖项,这些依赖项是链接 Spring 和 Jersey 所需的(有一个我不知道存在的 jersey-spring3 依赖项)。所以,现在我使用的关于 Spring 和 Jersey 的所有依赖项都是这些:

             <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,以便 Jersey 可以读取 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 确保 Web 配置“侦听”其他配置 xml 文件,这就是现在读取和使用 applicationContext.xml 的方式。并通过这些设置

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

      我确保将扫描我的包以查找 @Provider 和 @Path 注释,如果没有这些我的代码,我的服务将不会处于活动状态。 可以在此处阅读有关此提供程序包设置的更多信息:

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

      我希望我的问题和这个答案对所有有类似配置问题的人有用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-10-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-06
        • 1970-01-01
        • 2021-12-22
        • 2014-08-31
        相关资源
        最近更新 更多