Spring Data Repository - No qualifying bean Injection
autowired, dependency-injection, java, spring, spring-data-jpa
Solution
For JpaRepository to be picked by framework, you need to enable it in your configuration - add
@EnableJpaRepositories("your.package.with.jpa.repositories")
in your `@Configuration` file.
upd
here is sample configuration for jpa repositories to work:
@Bean
public DataSource dataSource(){
// configure your datasource
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
LocalContainerEntityManagerFactoryBean emfb = new LocalContainerEntityManagerFactoryBean();
emfb.setDataSource(dataSource);
emfb.setPackagesToScan("your.package.with.model");
emfb.setJpaVendorAdapter(jpaVendorAdapter());
emfb.setJpaPropertyMap(jpaPropertiesMap());
return emfb;
}
@Bean
public JpaVendorAdapter jpaVendorAdapter() {
return new HibernateJpaVendorAdapter();
}
@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
public Map<String, ?> jpaPropertiesMap() {
Properties properties = new Properties();
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect"); // assumption based on your pom-file
properties.setProperty("hibernate.hbm2ddl.auto", "..."); // you need to google for appropriate option
return properties;
}
Problem
I'm new to Spring framework. I just started learning following various guides (http://spring.io/guides) and I'm trying to complete the full tutorial about web services (http://spring.io/guides/tutorials/bookmarks/). I'm quite stuck on the JPA Datasource definition, because I get the following error ``` Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'init' defined in main.Application: Unsatisfied dependency expressed through constructor argument with index 0 of type [bookmarks.AccountRepository]: : No qualifying bean of type [bookmarks.AccountRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [bookmarks.AccountRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {} at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749) at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:464) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1111) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1006) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504) 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:762) 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:691) at org.springframework.boot.SpringApplication.run(SpringApplication.java:321) at org.springframework.boot.SpringApplication.run(SpringApplication.java:961) at org.springframework.boot.SpringApplication.run(SpringApplication.java:950) at main.Application.main(Application.java:41) Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [bookmarks.AccountRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {} at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1308) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1054) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:949) at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:813) at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741) ... 18 more ``` My main Application class is the following ``` @Configuration @ComponentScan @EnableAutoConfiguration public class Application { @Bean public CommandLineRunner init(AccountRepository accountRepository, BookmarkRepository bookmarkRepository) { System.out.println("Bean!"); return (evt) -> Arrays.asList( "jhoeller,dsyer,pwebb,ogierke,rwinch,mfisher,mpollack,jlong".split(",")) .forEach( a -> { Account account = accountRepository.save(new Account(a, "password")); bookmarkRepository.save(new Bookmark(account, "http://bookmark.com/1/" + a, "A description")); bookmarkRepository.save(new Bookmark(account, "http://bookmark.com/2/" + a, "A description")); }); } public static void main(String[] args) { SpringApplication.run(Application.class, args); } ``` And my pom.xml is ``` <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.test</groupId> <artifactId>demo</artifactId> <version>0.0.1</version> <packaging>jar</packaging> <name>demo</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.2.1.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <start-class>demo.DemoApplication</start-class> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-jpa</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> </dependency> <dependency> <groupId>javax.inject</groupId> <artifactId>javax.inject</artifactId> <version>1</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> ``` I understand that the dependency injection framework doesn't find any implementation of the AccountRepository interface, which looks like ``` public interface AccountRepository extends JpaRepository<Account, Long> { Optional<Account> findByUsername(String username); } ``` But the framework should provide "a correct implementation" for the JpaRepository. This is the part I'm not understanding. Any help would be appreciated, in particular with a pointer where to study in deep this framework. Thanks UPDATE Adding @EnableJpaRepositories("bookmarks") to the Application class, solved the bean resolution issue. But now I get Caused by: java.lang.IllegalArgumentException: Not an managed type: class bookmarks.Account My Account entity class is ``` import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToMany; import com.fasterxml.jackson.annotation.JsonIgnore; @Entity public class Account { @JsonIgnore public String password; public String username; @OneToMany(mappedBy="Account") private Set<Bookmark> bookmarks = new HashSet<>(); @Id @GeneratedValue private Long id; public Account(String name, String password) { this.username = name; this.password = password; } Account() { } // jpa only // getters and setters } ```