我正在尝试使用Spring Data创建一个从MySQL读取数据的框架。最终目标是能够编写自动化测试,可以从两个不同的MySQL dbs读取数据并比较数据(例如,确保数据正确复制)。我目前在实际使Spring代码工作时遇到了很多麻烦(我之前从未使用过Spring,我已经尝试修改我在网上找到的各种教程代码,但到目前为止还没有得到它工作。)
这就是我所拥有的。
的MySQL 表:凭证 columns:id(int),password_hash(string) 其中有4个条目。
项目布局:
src/main
groovy
domain
Credentials
repository
CredentialsRepository
resources
application.properties
src/test/groovy/
CredentialsTest
的build.gradle
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.4.3.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
jar {
baseName = 'gs-accessing-data-jpa'
version = '0.1.0'
}
repositories {
mavenCentral()
maven { url "https://repository.jboss.org/nexus/content/repositories/releases" }
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.4.7'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: '1.4.3.RELEASE'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: '1.4.3.RELEASE'
testCompile 'junit:junit:4.11'
}
application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/my_db
spring.datasource.username=my_user
spring.datasource.password=my_password
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.use_sql_comments=true
spring.jpa.properties.hibernate.format_sql=true
Credentials.groovy
package domain
import org.springframework.data.annotation.Id
import javax.persistence.Column
import javax.persistence.Entity
import javax.persistence.GeneratedValue
import javax.persistence.GenerationType
import javax.persistence.Table
@Entity
@Table(name = 'credentials')
class Credentials {
@Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name='id')
int id
@Column(name='password_hash')
String passwordHash
protected Credentials() {}
@Override
String toString() {
"Credential: [id=${id}, passwordHash=${passwordHash}]"
}
}
CredentialsRepository.groovy
package repository
import domain.Credentials
import org.springframework.data.repository.CrudRepository
interface CredentialsRepository extends CrudRepository<Credentials, Integer> {
}
CredentialsTest.groovy
import domain.Credentials
import repository.CredentialsRepository
import org.junit.Test
import org.junit.runner.RunWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner
import static org.junit.Assert.assertEquals
@RunWith(SpringJUnit4ClassRunner.class) //@EnableJpaRepositories(['domain.Credentials'])
@SpringBootTest(classes = MysqlJpaDemoApplication.class)
class CredentialsTest {
@Autowired
CredentialsRepository credentialsRepository
@Test
void testLoadCredentials() {
List<Credentials> credentialsList = credentialsRepository.findAll() as ArrayList<Credentials>
assertEquals(20, credentialsList.size())
}
}
运行testLoadCredentials测试会给出以下stacktrace:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'CredentialsTest': Unsatisfied dependency expressed through field 'credentialsRepository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'repository.CredentialsRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1225)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:386)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:118)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
at org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener.prepareTestInstance(SpringBootDependencyInjectionTestExecutionListener.java:44)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'repository.CredentialsRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1474)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1102)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1064)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
... 33 more
2016-12-28 14:14:32.638 INFO 39748 --- [ Thread-1] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@742ff096: startup date [Wed Dec 28 14:14:32 PST 2016]; root of context hierarchy
Process finished with exit code 255
答案 0 :(得分:1)
似乎您用于配置测试的应用程序类MysqlJpaDemoApplication
位于默认(顶级)包中。由于Spring在使用@ComponentScan
时会运行一些检查,因此会阻止您的应用程序扫描整个类路径。
您应该将MysqlJpaDemoApplication
移至新的包裹,即com.example
。您的源文件夹如下所示:
src/main
/groovy/com/example
|-- /domain
| |-- Credentials.groovy
|-- /repository
| |-- CredentialsRepository.groovy
|-- MysqlJpaDemoApplicatin.groovy
答案 1 :(得分:1)
看起来这就是它的工作原理:
com.example/
domain/
Credentials
repository/
CredentialsRepository
SpringConfig
Credentials.groovy
@Entity
@Table(name = 'credentials')
class Credentials {
@Id @GeneratedValue(strategy = GenerationType.AUTO)
int id
@Column(name='password_hash')
String passwordHash
protected Credentials() {}
@Override
String toString() {
"Credential: [id=${id}, passwordHash=${passwordHash}]"
}
}
CredentialsRepository
interface CredentialsRepository extends CrudRepository<Credentials, Integer> {}
SpringConfig.groovy
@Configuration
@EnableAutoConfiguration
@ComponentScan('com.example')
class SpringConfig {}
CredentialsTest.groovy
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=SpringConfig.class)
@SpringBootTest(classes = SpringConfig.class)
class CredentialsTest {
@Autowired
CredentialsRepository credentialsRepository
@Test
void testLoadCredentials() {
List<Credentials> credentialsList = credentialsRepository.findAll() as ArrayList<Credentials>
assertEquals(4, credentialsList.size())
}
}