java Spring Data Repository - 没有合格的 bean 注入
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28697462/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring Data Repository - No qualifying bean Injection
提问by besil
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/).
我是 Spring 框架的新手。我刚刚开始学习遵循各种指南 ( http://spring.io/guides) 并且我正在尝试完成有关 Web 服务的完整教程 ( http://spring.io/guides/tutorials/bookmarks/)。
I'm quite stuck on the JPA Datasource definition, because I get the following error
我非常坚持 JPA 数据源定义,因为我收到以下错误
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.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
我的 pom.xml 是
<?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
我知道依赖注入框架没有找到 AccountRepository 接口的任何实现,它看起来像
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.
但是框架应该为 JpaRepository 提供“正确的实现”。这是我不明白的部分。
Any help would be appreciated, in particular with a pointer where to study in deep this framework.
任何帮助将不胜感激,特别是提供深入研究该框架的指针。
Thanks
谢谢
UPDATEAdding @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
更新将@EnableJpaRepositories("bookmarks") 添加到Application 类,解决了bean 解析问题。但现在我得到了: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.Hymanson.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
}
回答by Vladimir
For JpaRepository to be picked by framework, you need to enable it in your configuration - add
要让框架选择 JpaRepository,您需要在配置中启用它 - 添加
@EnableJpaRepositories("your.package.with.jpa.repositories")
in your @Configuration
file.
在您的@Configuration
文件中。
upd
更新
here is sample configuration for jpa repositories to work:
这是 jpa 存储库工作的示例配置:
@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;
}
回答by besil
The final (working) configuration for solving the issues is the following (just following the documentation http://spring.io/guides/tutorials/bookmarks/).
解决问题的最终(工作)配置如下(仅遵循文档http://spring.io/guides/tutorials/bookmarks/)。
The solution was adding
解决方案是添加
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
in the pom.xml, and changing the
在 pom.xml 中,并更改
@OneToMany(mappedBy = "account")
private Set<Bookmark> bookmarks = new HashSet<>();
in the Account class (the error was: mappedBy="Account", capital letter...).
在 Account 类中(错误是:mappedBy="Account",大写字母...)。
Full code below:
完整代码如下:
pom.xml
pom.xml
<?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-SNAPSHOT</version>
<packaging>jar</packaging>
<name>MyRestService</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.MyRestServiceApplication</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-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Account class
账户类
package bookmarks;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import com.fasterxml.Hymanson.annotation.JsonIgnore;
@Entity
public class Account {
@OneToMany(mappedBy = "account")
private Set<Bookmark> bookmarks = new HashSet<>();
@Id
@GeneratedValue
private Long id;
public Set<Bookmark> getBookmarks() {
return bookmarks;
}
public Long getId() {
return id;
}
public String getPassword() {
return password;
}
public String getUsername() {
return username;
}
@JsonIgnore
public String password;
public String username;
public Account(String name, String password) {
this.username = name;
this.password = password;
}
Account() { // jpa only
}
}
Application class
应用类
@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application {
@Bean
CommandLineRunner init(AccountRepository accountRepository,
BookmarkRepository bookmarkRepository) {
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);
}
}