Can't Autowire @Repository annotated interface in Spring Boot
Asked Answered
S

23

136

I'm developing a spring boot application and I'm running into an issue here. I'm trying to inject a @Repository annotated interface and it doesn't seem to work at all. I'm getting this error

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

Here is my code:

Main application class:

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);
    }
}

Entity class:

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;

}

Repository interface:

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>{

}

Controller:

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

I even compared my code with Accessing data jpa, and I'm running out of ideas what's wrong with this code. Any help appreciated.

EDITED: I changed my code as suggested to look like above, and I'm not getting that error when I'm injecting my @Repository interface into another component. However, I have a problem now - my component cannot be retrieved (I used debugging). What I'm doing wrong so spring cannot find my component?

Spoonerism answered 23/3, 2015 at 22:29 Comment(1)
And what if you create another component and inject your 'UserEntityDao userEntityDao' to it? (also a sidenote: never inject dependencies directly to fields, use constructor with proper arguments and @Autowired/@Inject on it).Gallstone
I
234

When the repository package is different to @SpringBootApplication/@EnableAutoConfiguration, base package of @EnableJpaRepositories is required to be defined explicitly.

Try to add @EnableJpaRepositories("com.pharmacy.persistence.users.dao") to SpringBootRunner

Idle answered 13/5, 2015 at 8:2 Comment(10)
A little old, but adding @EnableJpaRepositories on the Application class did the trick.Malefactor
Strange docs says "By default, Spring Boot will enable JPA repository support and look in the package (and its subpackages) where @SpringBootApplication is located." spring.io/guides/gs/accessing-data-jpaEnfeoff
@magulla: OP's @SpringBootApplication located in package com.pharmacy.config, while @EnableJpaRepositories located in com.pharmacy.persistence.users.daoIdle
I had this same issue. Once I specified a package for my repositories, I received another error Entity is not a managed type. For anyone else having this issue, You also need to add the annotation @EntityScan("com.package.dtos")Holub
For MongoDB repositories add @EnableMongoRepositories("...")Flirt
Thanks for this answer! Note that supplying the repository package as a string will quietly break if the packages are reorganized. So a safer way to specify the repository package is @EnableJpaRepositories(basePackageClasses=MyRepository.class).Sandeesandeep
How does one do this when one does "Java Config" and not @ComponentScan?Malvia
I had the same issue, after applying the above solution and I removed @EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class}), it working.Thanks.Shagbark
Thanks, this worked like a charm. Don't know why it isn't showing as the topmost answer for this question.Radiopaque
For Redis reposotires add @EnableRedisRepositories("...")Carducci
C
61

I had the same issues with Repository not being found. So what I did was to move everything into 1 package. And this worked meaning that there was nothing wrong with my code. I moved the Repos & Entities into another package and added the following to SpringApplication class.

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

After that, I moved the Service (interface & implementation) to another package and added the following to SpringApplication class.

@ComponentScan("com...service")

This solved my issues.

Courtesan answered 31/3, 2016 at 7:10 Comment(1)
This should be the answer actually as it resolved the complete issue. as It gives not mapped type error after just adding @EnableJpaRepositoriesTaphole
C
52

There is another cause for this type of problem what I would like to share, because I struggle in this problem for some time and I could't find any answer on SO.

In a repository like:

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

}

If your entity UserEntity does not have the @Entity annotation on the class, you will have the same error.

This error is confusing for this case, because you focus on trying to resolve the problem about Spring not found the Repository but the problem is the entity. And if you came to this answer trying to test your Repository, this answer may help you.

Contextual answered 10/1, 2018 at 11:33 Comment(3)
Good shout! Thanks. For me I was using a redis repo, so defining the redish hash fixed it. e.g. @RedisHash(LanguageMapping.KEY_NAME)Thoughtout
This hint saved my day! Thanx a lot! I only had a wrong import so the typing of the repository was incompatible which led to the error message!Grim
Copied the same still with the SAME ERRORBroaddus
T
16

It seems your @ComponentScan annotation is not set properly. Try :

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

Actually you do not need the component scan if you have your main class at the top of the structure, for example directly under com.pharmacy package.

Also, you don't need both

@SpringBootApplication
@EnableAutoConfiguration

The @SpringBootApplication annotation includes @EnableAutoConfiguration by default.

Taunt answered 24/3, 2015 at 3:3 Comment(2)
Actually @ComponentScan("com.pharmacy") should do.Kazmirci
"Actually you do not need the component scan if you have your main class at the top of the structure" worked for me!Pleader
A
15

I had a similar issue where I was receiving NoSuchBeanDefinitionException in Spring Boot (basically while working on CRUD repository), I had to put the below annotations on the main class:

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

Also, make sure you have the @Component annotations in place on the implementations.

Abigael answered 19/6, 2017 at 19:49 Comment(0)
K
9

In SpringBoot, the JpaRepository are not auto-enabled by default. You have to explicitly add

@EnableJpaRepositories("packages")
@EntityScan("packages")
Kaczmarek answered 2/9, 2019 at 7:18 Comment(2)
Same issue I was facing, I had Repo and Entity in a library project, which was added as a dependency in an application project. There in the App.java need to enable these explicitly.Lyublin
Thank you, I had same issue as @FrancisRaj and after adding both @EnableJpaRepositories and @EntityScan with full package path, I could use my library project to connect with databaseBrazilein
A
6
@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
Amylose answered 30/3, 2020 at 7:17 Comment(1)
While this code may solve the question, including an explanation of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please edit your answer to add explanations and give an indication of what limitations and assumptions apply. From ReviewMozellamozelle
J
5

To extend onto above answers, You can actually add more than one package in your EnableJPARepositories tag, so that you won't run into "Object not mapped" error after only specifying the repository package.

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

}
Jeremyjerez answered 11/9, 2018 at 21:42 Comment(0)
W
5

I resolved that issue by changing that dependency :

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

With that one :

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

In that way there is no need to use Anotations like :

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

)

Wept answered 15/12, 2021 at 12:10 Comment(1)
After hours of trying to figure it out, this solved my issue. Thanks!Choochoo
W
4

You are scanning the wrong package:

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

Where as it should be:

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

Since your package names start with com and not org.

Wend answered 13/7, 2018 at 1:12 Comment(0)
P
3

It could be to do with the package you have it in. I had a similar problem:

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)

Action:

Consider defining a bean of type 'repository.UserRepository' in your configuration. "

Solved it by put the repository files into a package with standardised naming convention:

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

and

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

That way, spring knows where to go looking for the repositories, else things get confusing really fast. :)

Hope this helps.

Pater answered 23/10, 2019 at 13:42 Comment(0)
D
3

I had a similar issue with Spring Data MongoDB: I had to add the package path to @EnableMongoRepositories

Degraw answered 17/11, 2019 at 21:18 Comment(0)
P
2

I had some problems with this topic too. You have to make sure you define the packages in Spring boot runner class like this example below:

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

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

I hope this helps!

Parsons answered 12/5, 2018 at 9:50 Comment(0)
D
2

Here is the mistake: as someone said before, you are using org.pharmacy insted of com.pharmacy in componentscan

    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 {
Determined answered 18/7, 2018 at 11:55 Comment(1)
This is exactly the same as previous answerCrapulent
E
2

If you're facing this problem when unit testing with @DataJpaTest then you'll find the solution below.

Spring boot do not initialize @Repository beans for @DataJpaTest. So try one of the two fix below to have them available:

First

Use @SpringBootTest instead. But this will boot up the whole application context.

Second(Better solutions)

Import the specific repository you need, like below

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

@Autowired
private MyRepository myRepository;
Erdman answered 19/8, 2019 at 4:30 Comment(0)
G
1

I had a similar problem but with a different cause:

In my case the problem was that in the interface defining the repository

public interface ItemRepository extends Repository {..}

I was omitting the types of the template. Setting them right:

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

did the trick.

Greer answered 12/6, 2015 at 9:58 Comment(1)
Awesome. Only solution that helped me fix the issue;Pyrography
U
1

In @ComponentScan("org.pharmacy"), you are declaring org.pharmacy package. But your components in com.pharmacy package.

Unexpressive answered 8/7, 2019 at 8:3 Comment(0)
Z
1

Many of the answer up there help a lot, because they are part of the whole solution. For me it was a mix of some of them.

Your ComponentScan package is wrong. Change it to:

@ComponentScan("com.pharmacy")

You also have to add:

@EnableJpaRepositories

to your SpringBootApplication class, here: SpringBootRunner.

I had to change the Maven dependency (works similarly for Gradle):

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

To:

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

Don't forget to refresh your dependencies.

Then I also had to change my imports in my Entity class to:

import jakarta.persistence.*;
Zephaniah answered 18/10, 2022 at 5:1 Comment(0)
T
0

Make sure the @Service or @Component that is trying to auto-wire the repository isn't in the same directory as your SpringApplication.class. Make sure it's in a subfolder like service/.

Tortious answered 1/2, 2020 at 16:11 Comment(0)
S
0

Sometimes I had the same issues when I forget to add Lombok annotation processor dependency to the maven configuration

Scram answered 11/9, 2020 at 13:16 Comment(0)
D
0

Adding the below dependency on pom.xml solved the problem

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
Delphinedelphinia answered 14/1, 2022 at 1:53 Comment(0)
L
0

If your main class is in com.example package your other class should which are in different packages should be called in com.example package; i.e:Controller package com.example.controller

AND

Your Main class should be in com.example not in com.example.main if you gave the main class package as com.example.main then the other should be within that package e.g com.package.main.controller

Laughlin answered 26/4, 2022 at 12:32 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Delegate
G
0

You might be using Spring Data JPA in your pom.xml file.

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

Try replacing it with Spring Boot Starter Data JPA. It has all the necessary dependencies to fix the repository loading issue.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
Gaea answered 4/10, 2023 at 16:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.