无法在Spring Boot中自动装配@Repository带注释的界面


80

我正在开发一个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接口注入另一个组件时没有出现该错误。但是,我现在有一个问题-无法检索我的组件(我使用了调试)。我做错了什么,所以春天找不到我的零件?


而且,如果您创建另一个组件并向其中注入“ UserEntityDao userEntityDao”,该怎么办?(也是一个旁注:切勿将依赖项直接注入字段,使用带有适当参数的构造函数以及@ Autowired / @ Inject)。
拉法尔·G.2015年

Answers:


166

当存储库软件包不同于@SpringBootApplication/时@EnableAutoConfiguration@EnableJpaRepositories需要显式定义基础软件包。

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


4
有点旧,但是在Application类上添加@EnableJpaRepositories可以解决问题。
Hatem Jaber

4
奇怪的文档说:“默认情况下,Spring Boot将启用JPA存储库支持,并在@SpringBootApplication所在的包(及其子包)中查找。” spring.io/guides/gs/accessing-data-jpa
magulla

4
@magulla:OP@SpringBootApplication位于包中com.pharmacy.config,而@EnableJpaRepositories位于com.pharmacy.persistence.users.dao
hang321'3

28
我有同样的问题。为存储库指定软件包后,我将收到另一个错误Entity is not a managed type。对于其他遇到此问题的人,您还需要添加注释@EntityScan("com.package.dtos")
c.dunlap

2
对于MongoDB存储库,请添加@EnableMongoRepositories("...")
Omid

40

我也遇到了与找不到存储库相同的问题。所以我要做的就是将所有内容都放入1个程序包中。这有效意味着我的代码没有错。我将存储库和实体移到另一个包中,并将以下内容添加到SpringApplication类中。

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

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

@ComponentScan("com...service")

这解决了我的问题。


3
实际上,这应该是答案,因为它解决了整个问题。因为它给not mapped type刚刚加入后错误@EnableJpaRepositories
阿迪亚Peshave

24

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

在类似的存储库中:

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

}

如果实体UserEntity 不具有@Entity对类注释,你会有同样的错误。

对于这种情况,此错误令人困惑,因为您专注于尝试解决有关Spring的问题,但找不到存储库,但问题是实体。而且,如果您尝试测试存储库时得到了此答案,那么此答案可能会对您有所帮助。


1
砰! 工作了!谢谢。
sparkyspider19年

2
好喊!谢谢。对我来说,我使用的是redis仓库,因此定义红色哈希值可以解决该问题。例如@RedisHash(LanguageMapping.KEY_NAME)
–INtoy

16

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

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

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

另外,您不需要两者

@SpringBootApplication
@EnableAutoConfiguration

默认情况下,@SpringBootApplication注释包括在内@EnableAutoConfiguration


其实@ComponentScan("com.pharmacy")应该做的。
ci_

“实际上,如果您的主类位于结构的顶部,则不需要组件扫描。”
亚当

13

NoSuchBeanDefinitionException在Spring Boot中收到一个类似的问题(基本上是在CRUD存储库上工作时),我不得不在主类上放置以下注释:

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

另外,请确保@Component在实现上具有批注。


7

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

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

我遇到的同一问题,我在一个库项目中有Repo和Entity,这是作为依赖项添加到应用程序项目中的。App.java中需要显式启用这些功能。
弗朗西斯·拉吉

3

这是个错误:就像以前有人说过的那样,您正在组件容器中使用由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 {

3

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

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

}

3

您正在扫描错误的软件包:

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

应该在哪里:

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

由于您的软件包名称以com而不是org开头。


3
@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

2
虽然这段代码可以解决问题,但包括解释如何以及为什么解决该问题的说明,确实可以帮助提高您的帖子质量,并可能导致更多的投票。请记住,您将来会为读者回答问题,而不仅仅是现在问的人。请编辑您的答案以添加说明,并指出适用的限制和假设。来自评论
双响

1

我有类似的问题,但原因不同:

就我而言,问题是在定义存储库的接口中

public interface ItemRepository extends Repository {..}

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

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

做到了。


太棒了 唯一可以帮助我解决问题的解决方案;
Simran kaur

1

我对此主题也有一些疑问。您必须确保在Spring bootRunner类中定义软件包,如下例所示:

@SpringBootApplication
@EnableAutoConfiguration
@ComponentScan({"controller", "service"})
@EntityScan("entity")
@EnableJpaRepositories("repository")
public class Application {

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

我希望这有帮助!


1

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


1

如果在进行单元测试时遇到此问题 @DataJpaTest则可以在下面找到解决方案。

Spring Boot不初始化的@Repositorybean @DataJpaTest。因此,请尝试使用以下两个修复程序之一来使它们可用:

第一

使用@SpringBootTest代替。但这将启动整个应用程序上下文。

第二(更好的解决方案)

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

@DataJpaTest
@Import(MyRepository.class)
public class MyRepositoryTest {

@Autowired
private MyRepository myRepository;

1

这可能与您拥有的包装有关。我有一个类似的问题:

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便知道该去哪里寻找存储库,否则事情就会变得非常混乱。:)

希望这可以帮助。


1

我对Spring Data MongoDB有类似的问题:我必须将包路径添加到 @EnableMongoRepositories


0

确保@Service@Component正在试图自动线,仓库不是在同一目录下SpringApplication.class。确保它位于子文件夹中service/


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.