简体   繁体   中英

Autowiring :expected at least 1 bean which qualifies as autowire candidate for this dependency

Okay, I know that there are many questions asked around the same topic. But I cant seem to make anything work. It also might be the case that I am yet to completely understand the auto wiring concept. My Problem: I am able to get to the required page, but whenever I click on the any button to perform an action I get Null pointer exception which seems obvious as I dont think spring is able to properly map the bean needed.

So, when I add @autowired=true , it gives me the above given exceptionn. I am not sure what needs to be done.. Hope someone can help me out with this. Would love an explanation as well:) Code:

@Entity
@Table(name="userDetails")
public class UserDetailModel {

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public int user_id;
public String password;
public String user_name;
public String active_status;

public String getPassword() {
    return password;
}

public void setPassword(String password) {
    this.password = password;
}

public String getUser_name() {
    return user_name;
}

public void setUser_name(String user_name) {
    this.user_name = user_name;
}

public int getUser_id() {
    return user_id;
}

public void setUser_id(int user_id) {
    this.user_id = user_id;
}

public String getActive_status() {
    return active_status;
}

public void setActive_status(String active_status) {
    this.active_status = active_status;
}

}

Controller:

@RestController
public class UserDetailController {

 private Logger logger = (Logger) LoggerFactory.getLogger(UserDetailController.class);
 @Autowired(required = true)
private UserRepository userRepository;

@RequestMapping(value="/login", method = RequestMethod.POST)
public @ResponseBody String addNewUser (@RequestBody UserDetailModel user) {
    // @ResponseBody means the returned String is the response, not a view name
    // @RequestParam means it is a parameter from the GET or POST request

    logger.debug("in controller");
    UserDetailModel userDtl = new UserDetailModel();
    userDtl.setUser_id(user.user_id);
    userDtl.setUser_name(user.user_name);
    userDtl.setActive_status(user.active_status);
    userDtl.setPassword(user.password);

    userRepository.save(userDtl);
    return "Saved";
}

}

Repository:

@Repository
public interface UserRepository extends CrudRepository<UserDetailModel,         Long> {}

Stack Trace:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userDetailController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.springBoot.usl.repo.UserRepository com.springBoot.usl.controller.UserDetailController.userRepository; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.springBoot.usl.repo.UserRepository] 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:292)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:703)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:120)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:683)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:313)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:944)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:933)
at com.springBoot.usl.controller.WebAppInitializer.main(WebAppInitializer.java:18)

Solved based on the responses Answer: I made some modifications based on Jay and Luay's answers. And changed the annotations as follows in my ApplicationConfig file:

@Configuration
@ComponentScan("my.basepackage.*")
@EnableJpaRepositories(basePackages = {"my.basepackage.*"})
@EntityScan("my.basepackage.*")
@EnableAutoConfiguration

Hope this helps some one.

But I am not sure if * is the right way to go.

I am able to run your application with some changes on annotation side.

I have used same classes which are given in question. Please see below structure and configuration used. Directory Structure

I have used packages as below and added your classes,
com.rcmutha.usl.controller
com.rcmutha.usl.repository

@SpringBootApplication
@ComponentScan({"com.rcmutha*"})
@EntityScan("com.rcmutha*")
@EnableJpaRepositories("com.rcmutha*")
public class Application {

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

For complete code : click here for code

I think your application is not able to scan the UserRepository class, If you are using Spring Boot then you should put the main class on top of your package hierarchy.

You should also use @EnableJpaRepositories and tell it the base package of your repos to enable the repository functionality

@EnableJpaRepositories(basePackages ={"com.springBoot.usl.repo"})

UserRepository is simply not defined in the current Spring Context. Make sure that your class is defined in a package that is scanned by Spring. You will need to use @ComponentScan("org.my.pkg") in your Configuration class to make Spring scan the package.

If you're using Spring Boot, make sure you locate your main application class which is annotated with @SpringBootApplication in a root package above other classes, as it contains @ComponentScan .

You need to enable the JPA repositories in your config class, specify the package that contains the repositories as below

@Configuration
@EnableJpaRepositories(basePackages = {
    "com.springBoot.usl.repo"
})
public class ApplicationConfig {

}

Example of ApplicationConfig:

@Configuration
@EnableJpaRepositories(basePackages = {"com.springBoot.usl.repo"})
@EnableTransactionManagement
public class ApplicationConfig {

    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/xxxx");
        dataSource.setUsername("xxxx");
        dataSource.setPassword("xxxx");

        return dataSource;
    }

    @Bean
    public EntityManagerFactory entityManagerFactory() {
        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setGenerateDdl(true);
        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
        factory.setJpaVendorAdapter(vendorAdapter);
        factory.setPackagesToScan("xx.xxxx.xxxx.xxxx.domain");
        factory.setDataSource(dataSource());
        factory.afterPropertiesSet();
        return factory.getObject();
    }

    @Bean
    public PlatformTransactionManager transactionManager() {
        JpaTransactionManager txManager = new JpaTransactionManager();
        txManager.setEntityManagerFactory(entityManagerFactory());
        return txManager;
    }

I know that the problem was solved, but as it can be problem for someone else like I had, I decided to share my problem and the solution. I got exactly the same error message, but the problem was the lack of the annotation @Service in a class and hence an object of this type couldn't autowire. After putting this annotation, everything worked fine.

Below is the object of the mentioned class:

@Autowired
private JwtUserDetailsService jwtUserDetailsService;

Just this annotation caused the same problem and can pass unnoticed:

@Service  // annotation that was missing
public class JwtUserDetailsService implements UserDetailsService { ...

We had a similar problem in a kotlin + spring boot application and could solve it thanks to this solution slightly modified:

@SpringBootApplication
@ComponentScan("package.path*")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM