Spring Boot에서 @Repository 주석이 달린 인터페이스를 Autowire 할 수 없습니다.
나는 봄 부팅 응용 프로그램을 개발 중이며 여기서 문제가 발생합니다. @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 와 비교 했는데이 코드의 문제점 에 대한 아이디어가 부족합니다. 도움을 주시면 감사하겠습니다. 미리 감사드립니다.
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?
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
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.
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.
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.
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.
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{
}
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 {
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.
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!
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.
In @ComponentScan("org.pharmacy")
, you are declaring org.pharmacy
package. But your components in com.pharmacy
package.
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;
In SpringBoot, the JpaRepository are not auto-enabled by default. You have to explicitly add
@EnableJpaRepositories("packages")
@EntityScan("packages")
ReferenceURL : https://stackoverflow.com/questions/29221645/cant-autowire-repository-annotated-interface-in-spring-boot
'program tip' 카테고리의 다른 글
패턴과 일치하지 않는 파일을 나열 하시겠습니까? (0) | 2021.01.09 |
---|---|
Android 자료 : 상태 표시 줄 색상이 변경되지 않습니다. (0) | 2021.01.09 |
모든 문자열에서 마지막 세 문자 가져 오기-Java (0) | 2021.01.09 |
타임 스탬프를 건드리지 않고 업데이트 (Laravel) (0) | 2021.01.09 |
Sublimetext 3을 git commit 텍스트 편집기로 설정 (0) | 2021.01.09 |