【问题标题】:Can't Autowire @Repository annotated interface in Spring Boot无法在 Spring Boot 中自动装配 @Repository 注释接口
【发布时间】:2015-05-27 02:46:37
【问题描述】:

我正在开发一个 Spring Boot 应用程序,但在这里遇到了问题。我正在尝试注入 @Repository 带注释的接口,但它似乎根本不起作用。我收到此错误

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springBootRunner': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.pharmacy.persistence.users.dao.UserEntityDao com.pharmacy.config.SpringBootRunner.userEntityDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.pharmacy.persistence.users.dao.UserEntityDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1202)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:957)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:946)
    at com.pharmacy.config.SpringBootRunner.main(SpringBootRunner.java:25)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.pharmacy.persistence.users.dao.UserEntityDao com.pharmacy.config.SpringBootRunner.userEntityDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.pharmacy.persistence.users.dao.UserEntityDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
    ... 16 common frames omitted
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.pharmacy.persistence.users.dao.UserEntityDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1301)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1047)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
    ... 18 common frames omitted

这是我的代码:

主要应用类:

package com.pharmacy.config;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;


@SpringBootApplication
@ComponentScan("org.pharmacy")
public class SpringBootRunner {


    public static void main(String[] args) {
        SpringApplication.run(SpringBootRunner.class, args);
    }
}

实体类:

package com.pharmacy.persistence.users;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;



@Entity
public class UserEntity {

    @Id
    @GeneratedValue
    private Long id;
    @Column
    private String name;

}

存储库接口:

package com.pharmacy.persistence.users.dao;

import com.pharmacy.persistence.users.UserEntity;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;


@Repository
public interface UserEntityDao extends CrudRepository<UserEntity,Long>{

}

控制器:

package com.pharmacy.controllers;

import com.pharmacy.persistence.users.UserEntity;
import com.pharmacy.persistence.users.dao.UserEntityDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
public class HomeController {


    @Autowired
    UserEntityDao userEntityDao;

    @RequestMapping(value = "/")
    public String hello() {
        userEntityDao.save(new UserEntity("ac"));
        return "Test";

    }
}

build.gradle

buildscript {
    ext {
        springBootVersion = '1.2.2.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'spring-boot'
mainClassName = "com.pharmacy.config.SpringBootRunner"
jar {
    baseName = 'demo'
    version = '0.0.1-SNAPSHOT'
}


repositories {
    mavenCentral()
}


dependencies {
    compile("org.springframework.boot:spring-boot-starter-data-jpa")
    compile("org.springframework.boot:spring-boot-starter-web")
    compile("org.springframework.boot:spring-boot-starter-ws")
    compile("postgresql:postgresql:9.0-801.jdbc4")

    testCompile("org.springframework.boot:spring-boot-starter-test")
}

application.properties:

spring.view.prefix: /
spring.view.suffix: .html

spring.jpa.database=POSTGRESQL
spring.jpa.show-sql=false
spring.jpa.hibernate.ddl-auto=update


spring.datasource.driverClassName=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=postgres
spring.datasource.password=abc123

我什至将我的代码与Accessing data jpa 进行了比较,但我想不出这段代码有什么问题。 任何帮助表示赞赏。提前致谢。

已编辑:我按照上面的建议更改了我的代码,当我将 @Repository 接口注入另一个组件时,我没有收到该错误。但是,我现在有一个问题 - 我的组件无法检索(我使用了调试)。我做错了什么,所以 spring 找不到我的组件?

【问题讨论】:

  • 如果您创建另一个组件并将您的“UserEntityDao userEntityDao”注入它会怎样? (还有一个旁注:永远不要将依赖项直接注入字段,使用带有适当参数的构造函数并在其上使用@Autowired/@Inject)。

标签: spring spring-boot spring-data repository spring-data-jpa


【解决方案1】:

添加以下对 pom.xml 的依赖解决了问题

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

【讨论】:

    【解决方案2】:

    我通过改变依赖解决了这个问题:

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

    有了那个:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    

    这样就不需要使用像这样的注解:

    @EnableAutoConfiguration
    @ComponentScan({"controller", "service"})
    @EntityScan("entity")
    @EnableJpaRepositories("repository")
    

    )

    【讨论】:

      【解决方案3】:

      当我忘记将 Lombok 注释处理器依赖项添加到 maven 配置时,有时我会遇到同样的问题

      【讨论】:

        【解决方案4】:
        @SpringBootApplication(scanBasePackages=,<youur package name>)
        @EnableJpaRepositories(<you jpa repo package>)
        @EntityScan(<your entity package>)
        
        Entity class like below 
        @Entity
        @Table(name="USER")
        public class User {
        
            @Id
            @GeneratedValue
        

        【讨论】:

        • 虽然此代码可以解决问题,including an explanation 说明如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请edit您的答案以添加解释并说明适用的限制和假设。 From Review
        【解决方案5】:

        确保尝试自动连接存储库的@Service 或@Component 与您的SpringApplication.class 不在同一目录中。确保它位于 service/ 之类的子文件夹中。

        【讨论】:

          【解决方案6】:

          您正在扫描错误的包裹:

          @ComponentScan("**org**.pharmacy")
          

          应该在哪里:

          @ComponentScan("**com**.pharmacy")
          

          因为你的包名以 com 而不是 org 开头。

          【讨论】:

            【解决方案7】:

            我在使用 Spring Data MongoDB 时遇到了类似的问题:我必须将包路径添加到 @EnableMongoRepositories

            【讨论】:

              【解决方案8】:

              这可能与您的包裹有关。我遇到了类似的问题:

              Description:
              Field userRepo in com.App.AppApplication required a bean of type 'repository.UserRepository' that could not be found.
              
              The injection point has the following annotations:
                  - @org.springframework.beans.factory.annotation.Autowired(required=true)
              

              行动:

              考虑在您的配置中定义一个“repository.UserRepository”类型的 bean。 "

              通过将存储库文件放入具有标准化命名约定的包中来解决它:

              e.g. com.app.Todo (for main domain files)
              

              和

              com.app.Todo.repository (for repository files)
              

              这样,spring 知道去哪里寻找存储库,否则事情会很快变得混乱。 :)

              希望这会有所帮助。

              【讨论】:

                【解决方案9】:

                在 SpringBoot 中,JpaRepository 默认不自动启用。您必须明确添加

                @EnableJpaRepositories("packages")
                @EntityScan("packages")
                

                【讨论】:

                • 我遇到了同样的问题,我在一个库项目中有 Repo 和 Entity,它被添加为一个应用程序项目中的依赖项。在 App.java 中需要显式启用这些。
                • 谢谢,我和@FrancisRaj 有同样的问题,在添加了@EnableJpaRepositories 和@EntityScan 的完整包路径后,我可以使用我的库项目连接数据库
                【解决方案10】:

                如果您在使用@DataJpaTest 进行单元测试时遇到此问题,那么您将在下面找到解决方案。

                Spring boot 不会为 @DataJpaTest 初始化 @Repository bean。因此,请尝试以下两个修复之一以使它们可用:

                第一

                请改用@SpringBootTest。但这会启动整个应用程序上下文。

                第二(更好的解决方案)

                导入您需要的特定存储库,如下所示

                @DataJpaTest
                @Import(MyRepository.class)
                public class MyRepositoryTest {
                
                @Autowired
                private MyRepository myRepository;
                

                【讨论】:

                  【解决方案11】:

                  在@ComponentScan("org.pharmacy") 中,您声明了org.pharmacy 包。 但是您的组件在 com.pharmacy 包中。

                  【讨论】:

                    【解决方案12】:

                    我想分享导致此类问题的另一个原因,因为我在这个问题上挣扎了一段时间,但在 SO 上找不到任何答案。

                    在类似的存储库中:

                    @Repository
                    public interface UserEntityDao extends CrudRepository<UserEntity, Long>{
                    
                    }
                    

                    如果您的实体UserEntity 没有类上的@Entity 注释,您将遇到同样的错误。

                    这个错误在这种情况下令人困惑,因为您专注于尝试解决有关 Spring 未找到存储库但问题是实体的问题。如果您在尝试测试您的存储库时得到这个答案,this answer 可能会对您有所帮助。

                    【讨论】:

                    • 砰!工作!谢谢。
                    • 好声音!谢谢。对我来说,我使用的是 redis repo,所以定义 redish 哈希修复了它。例如@RedisHash(LanguageMapping.KEY_NAME)
                    【解决方案13】:

                    要扩展上述答案,您实际上可以在 EnableJPARepositories 标签中添加多个包,这样您就不会在仅指定存储库包后遇到“对象未映射”错误。

                    @SpringBootApplication
                    @EnableJpaRepositories(basePackages = {"com.test.model", "com.test.repository"})
                    public class SpringBootApplication{
                    
                    }
                    

                    【讨论】:

                      【解决方案14】:

                      这是错误:正如有人之前所说,您在 componentsscan 中使用了 com.pharmacy 的 org.pharmacy

                          package **com**.pharmacy.config;
                      
                          import org.springframework.boot.SpringApplication;
                          import org.springframework.boot.autoconfigure.SpringBootApplication;
                          import org.springframework.context.annotation.ComponentScan;
                      
                      
                          @SpringBootApplication
                          @ComponentScan("**org**.pharmacy")
                          public class SpringBootRunner {
                      

                      【讨论】:

                        【解决方案15】:

                        我在这个话题上也遇到了一些问题。 您必须确保在 Spring boot runner 类中定义包,如下例所示:

                        @SpringBootApplication
                        @EnableAutoConfiguration
                        @ComponentScan({"controller", "service"})
                        @EntityScan("entity")
                        @EnableJpaRepositories("repository")
                        public class Application {
                        
                            public static void main(String[] args){
                                SpringApplication.run(Application.class, args);
                            }
                        

                        我希望这会有所帮助!

                        【讨论】:

                          【解决方案16】:

                          我遇到了类似的问题,我在 Spring Boot 中收到了NoSuchBeanDefinitionException(基本上是在处理 CRUD 存储库时),我必须在主类上添加以下注释:

                          @SpringBootApplication   
                          @EnableAutoConfiguration
                          @ComponentScan(basePackages={"<base package name>"})
                          @EnableJpaRepositories(basePackages="<repository package name>")
                          @EnableTransactionManagement
                          @EntityScan(basePackages="<entity package name>")
                          

                          此外,请确保您在实现中使用了 @Component 注释。

                          【讨论】:

                            【解决方案17】:

                            我遇到了类似的问题,但原因不同:

                            在我的情况下,问题在于定义存储库的接口中

                            public interface ItemRepository extends Repository {..}
                            

                            我省略了模板的类型。正确设置它们:

                            public interface ItemRepository extends Repository<Item,Long> {..}
                            

                            成功了。

                            【讨论】:

                            • 太棒了。唯一能帮助我解决问题的解决方案;
                            【解决方案18】:

                            您的@ComponentScan 注释似乎设置不正确。 试试看:

                            @ComponentScan(basePackages = {"com.pharmacy"})
                            

                            实际上,如果您的主类位于结构的顶部,例如直接在com.pharmacy 包下,则不需要组件扫描。

                            另外,你不需要两者

                            @SpringBootApplication
                            @EnableAutoConfiguration
                            

                            @SpringBootApplication 注解默认包含@EnableAutoConfiguration。

                            【讨论】:

                            • 其实@ComponentScan("com.pharmacy")应该可以。
                            • “实际上,如果您的主类位于结构的顶部,则不需要组件扫描”对我有用!
                            【解决方案19】:

                            我遇到了同样的问题,即找不到存储库。所以我所做的就是把所有东西都放进一个包里。这意味着我的代码没有任何问题。我将 Repos & Entities 移动到另一个包中,并将以下内容添加到 SpringApplication 类中。

                            @EnableJpaRepositories("com...jpa")
                            @EntityScan("com...jpa")
                            

                            之后,我将服务(接口和实现)移动到另一个包中,并将以下内容添加到 SpringApplication 类中。

                            @ComponentScan("com...service")
                            

                            这解决了我的问题。

                            【讨论】:

                            • 这实际上应该是答案,因为它解决了完整的问题。因为它在添加@EnableJpaRepositories 后给出not mapped type 错误
                            【解决方案20】:

                            当仓库包与@SpringBootApplication/@EnableAutoConfiguration不同时,需要显式定义@EnableJpaRepositories的基础包。

                            尝试将@EnableJpaRepositories("com.pharmacy.persistence.users.dao")添加到SpringBootRunner

                            【讨论】:

                            • 有点旧,但是在 Application 类上添加 @EnableJpaRepositories 就可以了。
                            • 奇怪的文档说“默认情况下,Spring Boot 将启用 JPA 存储库支持并查看 @SpringBootApplication 所在的包(及其子包)。” spring.io/guides/gs/accessing-data-jpa
                            • @magulla:OP 的@SpringBootApplication 位于包com.pharmacy.config 中,而@EnableJpaRepositories 位于com.pharmacy.persistence.users.dao 中
                            • 我遇到了同样的问题。一旦我为我的存储库指定了一个包,我收到了另一个错误Entity is not a managed type。对于其他遇到此问题的人,您还需要添加注释@EntityScan("com.package.dtos")
                            • 对于 MongoDB 存储库添加 @EnableMongoRepositories("...")
                            猜你喜欢
                            • 2017-10-18
                            • 2016-10-03
                            • 2018-10-18
                            • 2019-06-23
                            • 1970-01-01
                            • 1970-01-01
                            • 2019-01-10
                            • 2018-12-27
                            • 2021-04-02
                            相关资源
                            最近更新 更多