Java spring jpa - 必须至少存在一个 JPA 元模型*
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43255169/
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 jpa - At least one JPA metamodel must be present*
提问by robyp7
Anybody know why it doesn't work?
有谁知道为什么它不起作用?
Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
06/04/2017 14:11:24.732 ERROR [main] - org.springframework.boot.SpringApplication: Application startup failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: At least one JPA metamodel must be present!
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1628)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:742)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:370)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:314)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1162)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1151)
at com.cadit.web.WebApplicationAware.main(WebApplicationAware.java:19)
Caused by: java.lang.IllegalArgumentException: At least one JPA metamodel must be present!
at org.springframework.util.Assert.notEmpty(Assert.java:277)
at org.springframework.data.jpa.mapping.JpaMetamodelMappingContext.<init>(JpaMetamodelMappingContext.java:52)
at org.springframework.data.jpa.repository.config.JpaMetamodelMappingContextFactoryBean.createInstance(JpaMetamodelMappingContextFactoryBean.java:71)
at org.springframework.data.jpa.repository.config.JpaMetamodelMappingContextFactoryBean.createInstance(JpaMetamodelMappingContextFactoryBean.java:26)
at org.springframework.beans.factory.config.AbstractFactoryBean.afterPropertiesSet(AbstractFactoryBean.java:134)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624)
... 16 common frames omitted
I defined entities in com.cadit.entities
:
我定义了实体com.cadit.entities
:
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="TEST")
public class GenericBeans implements BeanType, IEntity<Long> {
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "TEST_PAID")
protected Long id;
@Column(name = "SOCIETA")
private String SocietaCod;
@Column(name = "CONTO_INTERMEDIARIO")
private String contoInt;
@Column(name = "TIPO_OPERAZIONE")
private String tipoOpe;
public GenericBeans(String societaCod, String contoInt, String tipoOpe) {
SocietaCod = societaCod;
this.contoInt = contoInt;
this.tipoOpe = tipoOpe;
}
public GenericBeans() {
}
public String getSocietaCod() {
return SocietaCod;
}
public void setSocietaCod(String societaCod) {
SocietaCod = societaCod;
}
public String getContoInt() {
return contoInt;
}
public void setContoInt(String contoInt) {
this.contoInt = contoInt;
}
public String getTipoOpe() {
return tipoOpe;
}
public void setTipoOpe(String tipoOpe) {
this.tipoOpe = tipoOpe;
}
@Override
public String toString() {
return "CSV [SocietaCod=" + SocietaCod + ", contoInt=" + contoInt + ", tipoOpe=" + tipoOpe + "]";
}
@Override
public Long getId() {
return this.id;
}
@Override
public void setId(Long id) {
this.id=id;
}
}
I definied my datasource
entry definition for spring:
我datasource
为 spring 定义了我的入口定义:
import org.apache.log4j.Logger;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@ComponentScan
@EntityScan("com.cadit.entities")
//@EnableJpaRepositories("com.cadit.entities")
@EnableTransactionManagement
@PropertySource("classpath:db-config.properties")
public class DbAutoConfiguration {
static final Logger logger = Logger.getLogger(DbAutoConfiguration.class);
public DbAutoConfiguration() {
}
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource(){
//DataSource ds =new EmbeddedDatabaseBuilder().addScript("classpath:sql/schema.sql").addScript("classpath:testdb/data.sql").build();
DataSourceBuilder ds = DataSourceBuilder.create();
logger.info("dataSource = " + ds);
return ds.build();
}
}
My db-config.properties
is:
我的db-config.properties
是:
spring.jpa.hibernate.ddl-auto: validate
spring.jpa.hibernate.naming_strategy: org.hibernate.cfg.ImprovedNamingStrategy
#spring.jpa.database: SQL
spring.jpa.show-sql: true
spring.datasource.driverClassName=net.sourceforge.jtds.jdbc.Driver
spring.datasource.url=jdbc:jtds:sqlserver://localhost:1433;databaseName=example
spring.datasource.username=xxx
spring.datasource.password=xxx
IEntity
is:
IEntity
是:
public interface IEntity <I extends Serializable> extends Serializable{
/**
* Property rappresenta la primary key.
*/
String P_ID = "id";
/**
* restituisce la primary key
* @return
*/
I getId();
/**
* imposta la primary key
* @param id
*/
void setId(I id);
}
I try to write CSV file to database using CrudRepository
interface of spring:
我尝试使用CrudRepository
spring 接口将 CSV 文件写入数据库:
import java.io.File;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.repository.CrudRepository;
import com.cadit.entities.GenericBeans;
import com.csvreader.CsvReader;
public class CsvReaders {
static final Logger logger = Logger.getLogger(CsvReader.class);
@Autowired
public CrudRepository<GenericBeans,Long> _entitymanager;
public List loadDataFromCsv(String fileName) {
try {
File file = new ClassPathResource(fileName).getFile();
CsvReader csv = new CsvReader(file.getAbsoluteFile().getPath(),';');
csv.readHeaders();
List l = new LinkedList();
GenericBeans b = new GenericBeans ();
while (csv.readRecord())
{
b.setSocietaCod(csv.get(0));
b.setContoInt(csv.get(1));
b.setTipoOpe(csv.get(2));
_entitymanager.save(b); //persist on db
l.add(b);
b = new GenericBeans();
}
b=null;
return l;
} catch (Exception e) {
logger.error("Error occurred while loading object list from file " + fileName, e);
return Collections.emptyList();
}
}
}
I DO NOT use main
class but a class which extend SpringBootServletInitializer
because i want to run it on both standalone tomcat and Tomcat installation as WAR application
我不使用main
类,而是使用扩展的类,SpringBootServletInitializer
因为我想在独立的 tomcat 和 Tomcat 安装上运行它作为 WAR 应用程序
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages={"com.cadit.entities","com.cadit.beans"})
@EnableAutoConfiguration
public class WebApplicationAware extends SpringBootServletInitializer {
private static Class<WebApplicationAware> applicationClass = WebApplicationAware.class;
public static void main(String[] args) {
SpringApplication.run(applicationClass, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(applicationClass);
}
}
All properties file are in classpath resources because it's a maven project.
所有属性文件都在类路径资源中,因为它是一个 Maven 项目。
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.springframework</groupId>
<artifactId>xxxx</artifactId>
<version>0.1.0</version>
<packaging>war</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.11.1.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0.2</version>
</dependency>
<!-- altre dipendenze non spring -->
<!-- https://mvnrepository.com/artifact/net.sourceforge.javacsv/javacsv -->
<dependency>
<groupId>net.sourceforge.javacsv</groupId>
<artifactId>javacsv</artifactId>
<version>2.0</version>
</dependency>
<!-- per jpa solo se si usa il Tomcat embedded -->
<dependency>
<groupId>net.sourceforge.jtds</groupId>
<artifactId>jtds</artifactId>
<version>1.3.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
<!-- end -->
<!-- dipendenze logback -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.5</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.7</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.7</version>
</dependency>
<!-- fine dip logback -->
</dependencies>
<properties>
<start-class>hello.WebApplicationAware</start-class>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<repositories>
<repository>
<id>spring-releases</id>
<url>https://repo.spring.io/libs-release</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-releases</id>
<url>https://repo.spring.io/libs-release</url>
</pluginRepository>
</pluginRepositories>
</project>
What's the problem, why doesn't it find JPA entities when I run WebApplicationAware class?
有什么问题,为什么在我运行 WebApplicationAware 类时找不到 JPA 实体?
采纳答案by Stefan Isele - prefabware.com
Spring does not find any JPA Entities, so no JPA Meta Model is created, that is why you face the exception.
Spring 找不到任何 JPA 实体,因此没有创建 JPA 元模型,这就是您面临异常的原因。
The cause of this problem may be a wrong persistence-api version on your class path.
此问题的原因可能是您的类路径上的持久性 API 版本错误。
You are using
您正在使用
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0.2</version>
</dependency>
but I am pretty shure your spring version uses persistence-api version 2.
但我很确定你的 spring 版本使用了持久性 API 版本 2。
Could it be, you are using @Entity annotation from version 1 ? At runtime spring uses version 2, and this is searching for Entites using @Entity from version 2 only !
可能是,您正在使用版本 1 中的 @Entity 注释?在运行时,spring 使用版本 2,这只是使用版本 2 中的 @Entity 搜索实体!
Remove the dependencies
删除依赖项
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.11.1.RELEASE</version>
</dependency>
Instead add
而是添加
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
This will give you all JPA dependencies in the right version.
这将为您提供正确版本的所有 JPA 依赖项。
回答by Abdeali Chandanwala
I solved it by adding 2 annotations
我通过添加 2 个注释解决了它
@EnableAutoConfiguration
@EntityScan(basePackages = { "com.wt.rds" })
and my dependency was in gradle
我的依赖是在 gradle
compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: '2.0.4.RELEASE'
回答by 99Sono
Unfortunately, most of the springboot guides on JPA integration test often lack a piece of configuration here and there.
不幸的是,大多数关于 JPA 集成测试的 springboot 指南经常在这里和那里缺乏配置。
So here is an example that hopefully should just work for you.
所以这里有一个例子,希望它适合你。
Point 1. My local environment is currently setup to use springboot version:
Point 1.我的本地环境目前设置为使用springboot版本:
<version.spring.boot>1.5.9.RELEASE</version.spring.boot>
That being said, I am currently setting up my local environment to be able to run integration tests against multiple databases (e.g. postgres, hsql, h2). Therefore, I start by googling any random toturial that approaches this problem.
话虽如此,我目前正在设置我的本地环境,以便能够针对多个数据库(例如 postgres、hsql、h2)运行集成测试。因此,我首先在谷歌上搜索任何解决这个问题的随机toturial。
The next link is one such example:
下一个链接就是一个这样的例子:
https://www.baeldung.com/spring-testing-separate-data-source
https://www.baeldung.com/spring-testing-separate-data-source
The above example is a good starting point. It allows you to scoop up a valid Entity and a Valid repository. The springboot test class itself, on the other hand, leaves a lot ot be desired.
上面的例子是一个很好的起点。它允许您获取有效的实体和有效的存储库。另一方面,springboot 测试类本身还有很多不足之处。
With the above example, you will immediately struggle with the integration test. You will get the usuable problems about the example not giving you the application.class to configure the integration test, and you are left hanging clueless as to what springboot annotations you need to put "where" to make the test to finally run without explosions.
使用上面的示例,您将立即与集成测试斗争。您将遇到有关示例的可用问题,没有为您提供 application.class 来配置集成测试,并且您对需要将哪些 springboot 注释放在“位置”以使测试最终运行而没有爆炸一无所知。
So now I give you a MINIMAL set of 3 classes (Entity + Repository + SpringbootTest) that should hopefully have 100 percent of the configuration you need. This will serve as a basis of any JPA based integration test you will need to do in the future, then you can swap your entities and repositories, and continue testing with the same type of srpingboot configuration.
所以现在我给你一个 3 个类的最小集合(Entity + Repository + SpringbootTest),它们应该有你需要的 100% 的配置。这将作为您将来需要进行的任何基于 JPA 的集成测试的基础,然后您可以交换您的实体和存储库,并继续使用相同类型的 srpingboot 配置进行测试。
I start by giving you the IRRELEVANT classes. The stuff that is always the same, the stuff that you want to test, and that has nothing to do with configuration. I am referring to REPOSITORY + ENTITY.
我首先为您提供 IRRELEVANT 课程。始终相同的东西,您要测试的东西,与配置无关。我指的是存储库 + 实体。
In eclipse create your java package: tutorial.www.baeldung.com.tutorial001jpa.separateDS
在eclipse中创建你的java包:tutorial.www.baeldung.com.tutorial001jpa.separateDS
Dump into this package the following trivial entity and repository classes, that are based on the tutorial reference I gave above.
将以下基于我上面给出的教程参考的简单实体和存储库类转储到此包中。
Tutorial001GenericEntity
package tutorial.www.baeldung.com.tutorial001jpa.separateDS;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "TUTORIAL_001_GENERIC_ENTITY")
public class Tutorial001GenericEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String value;
public Tutorial001GenericEntity() {
super();
}
public Tutorial001GenericEntity(String value) {
super();
this.value = value;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
// standard constructors, getters, setters
}
Then we go for the second trivial code snippet. The spring repository boiler plate code.
然后我们去寻找第二个简单的代码片段。spring 存储库样板代码。
Tutorial001GenericEntityRepository
package tutorial.www.baeldung.com.tutorial001jpa.separateDS;
import org.springframework.data.jpa.repository.JpaRepository;
public interface Tutorial001GenericEntityRepository extends JpaRepository<Tutorial001GenericEntity, Long> {
}
At this point your maven project, src/test/java has a total of two classes. The basic stuff. An entity and a repository, that serve as an example of any integration test you will ever need to do.
此时你的maven项目src/test/java一共有两个类。基本的东西。一个实体和一个存储库,作为您需要执行的任何集成测试的示例。
So now you go to the only important class in the example, the stuff that always gives a lot of problems, and that is the springboot test class which more then being responsible to test your business logic also has the complex task of CONFIGURING your test.
因此,现在您转到示例中唯一重要的类,该类总是会出现很多问题,那就是 springboot 测试类,它不仅负责测试您的业务逻辑,还具有 CONFIGURING 您的测试的复杂任务。
In this case, this test class has ALL IN ONE the annotations that allow springboot to disocver your entities, repositories, etc...
在这种情况下,这个测试类有一个注释,允许 springboot 发现你的实体、存储库等......
package tutorial.www.baeldung.com.tutorial001jpa.separateDS;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {
tutorial.www.baeldung.com.tutorial001jpa.separateDS.Tutorial001GenericEntityIntegrationTest.ConfigureJpa.class })
@SpringBootTest()
public class Tutorial001GenericEntityIntegrationTest {
@EntityScan(basePackageClasses = { Tutorial001GenericEntity.class })
@EnableJpaRepositories(basePackageClasses = Tutorial001GenericEntity.class)
@EnableAutoConfiguration()
public static class ConfigureJpa {
}
@Autowired
private Tutorial001GenericEntityRepository genericEntityRepository;
@Test
public void givenTutorial001GenericEntityRepository_whenSaveAndRetreiveEntity_thenOK() {
Tutorial001GenericEntity genericEntity = genericEntityRepository.save(new Tutorial001GenericEntity("test"));
Tutorial001GenericEntity foundEntity = genericEntityRepository.findOne(genericEntity.getId());
assertNotNull(foundEntity);
assertEquals(genericEntity.getValue(), foundEntity.getValue());
}
}
The important thing, you see, is that this spring boot test has a class level annotation to provide to the springboot test the configuration context.
你看,重要的是这个 spring boot 测试有一个类级别的注释,为 springboot 测试提供配置上下文。
What we are doing is dumping one and only one class reference that represents our test configuration. tutorial.www.baeldung.com.tutorial001jpa.separateDS.Tutorial001GenericEntityIntegrationTest.ConfigureJpa.class
我们正在做的是转储一个且仅一个代表我们的测试配置的类引用。tutorial.www.baeldung.com.tutorial001jpa.separateDS.Tutorial001GenericEntityIntegrationTest.ConfigureJpa.class
And then on this little guy, you put all of the additional annotations in the world you need that springboot offers to configure applications.
然后在这个小家伙身上,您将 springboot 提供的用于配置应用程序所需的所有附加注释放在世界上。
In this case we have a dedicated annotation to mention entities. Another to mention repositories. And another to tell springboot to activate its auto configuration.
在这种情况下,我们有一个专门的注释来提及实体。另一个提到存储库。另一个告诉 springboot 激活它的自动配置。
This springboot auto configuration annotation then does additional vodoo, like looking at your classpath and seeing that you have in the classpath say:
这个 springboot 自动配置注释然后做了额外的 vodoo,比如查看你的类路径并看到你在类路径中说:
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>test</scope>
<version>2.3.4</version>
</dependency>
And it will immediately know how to configure an in memory data source for this database.
它会立即知道如何为该数据库配置内存数据源。
Behind the scenes, there might be additional configuration that is getting used. For example, if you create an application.properties file in your src/test/resources that file will be considered. It is very to see that the appliction.properties is considered by your running test.
在幕后,可能会使用其他配置。例如,如果您在 src/test/resources 中创建 application.properties 文件,则会考虑该文件。很明显您的运行测试考虑了 appliction.properties。
If you want to verify this, make sure that in your test setup you do not have, for example, any dependency on the JDBC driver for postgres. And then put into your application.properties something liek this:
如果您想验证这一点,请确保在您的测试设置中您没有,例如,对 postgres 的 JDBC 驱动程序的任何依赖。然后在您的 application.properties 中放入以下内容:
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
This dialect is not compatible with HSQL or H2, so it will immediately make your green passing integration test blow up.
这种方言与HSQL或H2不兼容,所以它会立即让你的绿色通过集成测试爆炸。
To be honest, I do not know if there is a simpler combo of annotations to properly configure the springboot scanning for an integration test.
老实说,我不知道是否有更简单的注解组合来正确配置用于集成测试的springboot扫描。
As a rule, I would recommend that you try avoiding having hundreds of thousands of configuration classes in your src/test/resources. Because if at some point you want to toggle all of your integration tests from using applicat-postgres.proeprties to application-hsql.properties, you might find yourself needing to tweak multiple configuration classes instead of just one.
通常,我建议您尽量避免在 src/test/resources 中包含数十万个配置类。因为如果在某个时候您想将所有集成测试从使用 applicat-postgres.proeprties 切换到 application-hsql.properties,您可能会发现自己需要调整多个配置类,而不仅仅是一个。
So as rule, per maven component you write, I would try to have the tests that check repositories extend some sort of MyBaseINtegrationTestClass, and in there put this
因此,作为规则,对于您编写的每个 Maven 组件,我会尝试让检查存储库的测试扩展某种 MyBaseINtegrationTestClass,并在其中放置
@ContextConfiguration(classes = {
tutorial.www.baeldung.com.tutorial001jpa.separateDS.Tutorial001GenericEntityIntegrationTest.ConfigureJpa.class })
So that you only need to play with one configuration for testing for the hole project.
这样您只需要使用一种配置来测试孔项目。
IN any case, hopefully the triplet of classes given here helps you.
无论如何,希望这里给出的三重课程可以帮助您。
One finel thing, for maven dependencies for integration testing, here is what I am using:
一件很好的事情,对于集成测试的 Maven 依赖项,这是我正在使用的:
<!-- Test Dependencies JPA REPOSITORY TESTS -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
The reason why i am using hsql and h2 is beacuse I want my integration tests to be able to be tunned to either use application-hsql or application-h2.properties.
我使用 hsql 和 h2 的原因是因为我希望我的集成测试能够被调整为使用 application-hsql 或 application-h2.properties。