我不能在春天自动装配存储库

Posted

技术标签:

【中文标题】我不能在春天自动装配存储库【英文标题】:I can't autowire repository in spring 【发布时间】:2016-08-10 11:45:22 【问题描述】:

我正在尝试使用 spring 注释在控制器中自动装配存储库。我收到了错误org.springframework.data.repository.query.QueryByExampleExecutor class not found,我找不到解决方案。

我得到的错误:

SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'articleController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.payforeign.article.ArticleRepository com.payforeign.article.ArticleController.repository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'articleRepository': Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: org/springframework/data/repository/query/QueryByExampleExecutor

控制器

package com.payforeign.article;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/service")
public class ArticleController 

   @Autowired
   private ArticleRepository repository;

   //controller methods

存储库

我用@Repository 注释了存储库。根据spring文档,我只有存储库接口。对吗?

package com.payforeign.article;

import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface ArticleRepository extends CrudRepository<Article, Long> 

applicationContext.xml

我已将jpa:repositories 包含在正确的base-packagecomponent-scan 中。我已指定它是注释驱动的 (&lt;mvc:annotation-driven /&gt; &lt;tx:annotation-driven /&gt;) 并添加了 JDBC 和 JPA 设置。我的 applicationContext.xml 是从 web.xml 正确加载的

<?xml version='1.0' encoding='UTF-8' ?>
<beans ...>
    <context:component-scan base-package="com.payforeign,com.payforeign.article" />
    <mvc:annotation-driven />
    <jpa:repositories base-package="com.payforeign.article" />

    <!-- Data Source -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" >
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost/payforeign" />
        <property name="username" value="root" />
        <property name="password" value="" />
    </bean>

    <!-- Hibernate -->
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="packagesToScan" value="com.payforeign.article" />
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="showSql" value="true" />
                <property name="generateDdl" value="true" />
                <property name="database" value="MYSQL" />
            </bean>
        </property>
    </bean>

    <!-- enable the configuration of transactional behavior based on annotations -->
    <tx:annotation-driven />
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>
</beans>

【问题讨论】:

堆栈跟踪很清楚:您的 CLASSPATH 中缺少 Spring Data JAR。 NoClassDefFoundError 几乎总是意味着版本不匹配。在这种情况下,我相信您需要 RC 版本(或至少是最新的发布版本)来获取示例查询。 我已将spring-data-commons 从版本 1.11.4 升级到 1.12.1 并解决了问题。谢谢@chrylis 【参考方案1】:

尝试在您的 applicationContext.xml 中添加此配置

<context:annotation-config/>

【讨论】:

根据http://***.com/a/7456501/1997088 &lt;context:component-scan&gt; 的回答可以完成&lt;context:annotation-config/&gt; 的工作,然后不需要注释配置【参考方案2】:

请更换

<context:component-scan base-package="com.payforeign,com.payforeign.article" />

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

使用它定义基本包,您 com.payforeign.article 将自动扫描。

【讨论】:

【参考方案3】:

您的问题与依赖关系有关。

您正在寻找的课程在这里: https://github.com/spring-projects/spring-data-jpa/blob/master/src/main/java/org/springframework/data/jpa/repository/JpaRepository.java

如您所见,最新版本的 spring-data-jpa 具有它,因此您应该将失败的 delendency 升级到最新版本或稍微降级 spring-data-jpa 版本(不推荐)。

我的应用程序在使用 spring boot 和 mongoDB jpa 存储库时遇到了类似的问题。

例如,我有 spring-data-jpa 和 spring-data-mongodb 依赖项:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency> 
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-mongodb</artifactId>
    <version>1.9.2.RELEASE</version>
</dependency>

但是 spring boot spring-boot-starter-data-jpa 隐式使用了比 1.9.2.RELEASE 更旧版本的 spring-data-mongodb。 最简单的修复方法是将 spring-data-mongodb 降级到 1.8.4.RELEASE 版本。

【讨论】:

【参考方案4】:

如果spring-data-commons 的版本比spring-data-jpa 要求的版本旧,您可能会遇到NoClassDefFoundError。这个异常几乎总是意味着版本不匹配(依赖地狱)。下面是这样一个糟糕的依赖组合的例子:

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-commons</artifactId>
    <version>1.6.2.RELEASE</version>
</dependency>

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

解决方案就像从项目依赖项中删除 spring-data-commons 一样简单(无论如何,您不需要显式指定此库,因为它是 spring-data-jpa 的传递依赖项)。

【讨论】:

我从我的 pom 中引用了多个 spring-data 依赖项,即 spring-boot-starter-data-jpa 和 spring-boot-starter-data-rest,这导致了麻烦。删除不需要的东西解决了我的问题。这个答案帮助我得到了这个想法。

以上是关于我不能在春天自动装配存储库的主要内容,如果未能解决你的问题,请参考以下文章

使用 @DataJpaTest 的 Spring 测试无法使用 @Repository 自动装配类(但使用接口存储库可以工作!)

@Primary 等效于自动装配的 Spring JPA 存储库

在 Spring 中将多个存储库自动装配到单个 DAO 中 - 不好的做法?

Spring Boot:来自库项目的自动装配 bean

关于 JPA 存储库和自动装配的 Java spring 问题

尽管有 @EnableJpaRepositories 注释,但 Spring JPA 未实现/自动装配存储库