具有多个 DataSource bean 的 AutoConfigureTestDatabase
AutoConfigureTestDatabase with multiple DataSource beans
我的应用程序中有两个数据源,它们在实时环境中连接到数据库时按预期工作。但是,在为此应用程序编写单元测试时,我的 bean 定义遇到了问题。
这是我的主要数据源配置:
@Configuration
@EnableJpaRepositories(
basePackages = "foo.bar.repository.primary",
entityManagerFactoryRef = "primaryEntityManager",
transactionManagerRef = "primaryTransactionManager")
public class PrimaryDataSourceConfig {
@Bean
@Primary
@ConfigurationProperties("primary.datasource")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@Primary
public LocalContainerEntityManagerFactoryBean primaryEntityManager() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(primaryDataSource());
em.setPackagesToScan("foo.bar.domain.entity");
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
Map<String, String> properties = new HashMap<>();
properties.put("hibernate.implicit_naming_strategy",
"org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy");
properties.put("hibernate.physical_naming_strategy",
"org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy");
em.setJpaPropertyMap(properties);
return em;
}
@Bean
@Primary
public PlatformTransactionManager primaryTransactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(primaryEntityManager().getObject());
return transactionManager;
}
}
我有一个测试,我想做的就是启动整个应用程序上下文,看起来像这样。
@AutoConfigureTestDatabase
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class ErpApplicationTest {
@Test
public void test() {
// Application started
}
}
然而,当我运行这个测试时,我得到以下错误:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'primaryEntityManager' defined in class path resource [foo/bar/primaryDataSourceConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean]: Factory method 'primaryEntityManager' threw exception; nested exception is java.lang.IllegalArgumentException: No visible constructors in class org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration$EmbeddedDataSourceFactoryBean
是什么导致了这个错误,我该怎么做才能纠正它? Flyway 能够连接到注释生成的嵌入式 H2 实例和 运行 它的迁移,但是主数据源及其 EntityManager 在创建时失败。
我通过执行以下操作解决了这个问题:
首先,我将 AutoConfigureTestDatabase-annotation 更改为不替换任何数据源:
@AutoConfigureTestDatabase(
replace = AutoConfigureTestDatabase.Replace.NONE)
我现在遇到数据库超时错误。由于 AutoConfig 默认为 in-memory h2,我认为之前的数据库连接设置不正确。我更改了我的应用程序。properties-file 以包含以下内容:
primary.datasource.driver-class-name=org.h2.Driver
primary.datasource.jdbc-url=jdbc:h2:~;MODE=MYSQL
primary.datasource.username=
primary.datasource.password=
secondary.datasource.driver-class-name=org.h2.Driver
secondary.datasource.jdbc-url=jdbc:h2:~;MODE=MYSQL
secondary.datasource.username=
secondary.datasource.password=
大概是因为自动配置无法为我的自定义数据源正确替换 entityManager 而发生此错误。通过确保数据源未被替换,并确保连接 url 正确,测试按预期进行。
我的应用程序中有两个数据源,它们在实时环境中连接到数据库时按预期工作。但是,在为此应用程序编写单元测试时,我的 bean 定义遇到了问题。
这是我的主要数据源配置:
@Configuration
@EnableJpaRepositories(
basePackages = "foo.bar.repository.primary",
entityManagerFactoryRef = "primaryEntityManager",
transactionManagerRef = "primaryTransactionManager")
public class PrimaryDataSourceConfig {
@Bean
@Primary
@ConfigurationProperties("primary.datasource")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@Primary
public LocalContainerEntityManagerFactoryBean primaryEntityManager() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(primaryDataSource());
em.setPackagesToScan("foo.bar.domain.entity");
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
Map<String, String> properties = new HashMap<>();
properties.put("hibernate.implicit_naming_strategy",
"org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy");
properties.put("hibernate.physical_naming_strategy",
"org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy");
em.setJpaPropertyMap(properties);
return em;
}
@Bean
@Primary
public PlatformTransactionManager primaryTransactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(primaryEntityManager().getObject());
return transactionManager;
}
}
我有一个测试,我想做的就是启动整个应用程序上下文,看起来像这样。
@AutoConfigureTestDatabase
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class ErpApplicationTest {
@Test
public void test() {
// Application started
}
}
然而,当我运行这个测试时,我得到以下错误:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'primaryEntityManager' defined in class path resource [foo/bar/primaryDataSourceConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean]: Factory method 'primaryEntityManager' threw exception; nested exception is java.lang.IllegalArgumentException: No visible constructors in class org.springframework.boot.test.autoconfigure.jdbc.TestDatabaseAutoConfiguration$EmbeddedDataSourceFactoryBean
是什么导致了这个错误,我该怎么做才能纠正它? Flyway 能够连接到注释生成的嵌入式 H2 实例和 运行 它的迁移,但是主数据源及其 EntityManager 在创建时失败。
我通过执行以下操作解决了这个问题:
首先,我将 AutoConfigureTestDatabase-annotation 更改为不替换任何数据源:
@AutoConfigureTestDatabase(
replace = AutoConfigureTestDatabase.Replace.NONE)
我现在遇到数据库超时错误。由于 AutoConfig 默认为 in-memory h2,我认为之前的数据库连接设置不正确。我更改了我的应用程序。properties-file 以包含以下内容:
primary.datasource.driver-class-name=org.h2.Driver
primary.datasource.jdbc-url=jdbc:h2:~;MODE=MYSQL
primary.datasource.username=
primary.datasource.password=
secondary.datasource.driver-class-name=org.h2.Driver
secondary.datasource.jdbc-url=jdbc:h2:~;MODE=MYSQL
secondary.datasource.username=
secondary.datasource.password=
大概是因为自动配置无法为我的自定义数据源正确替换 entityManager 而发生此错误。通过确保数据源未被替换,并确保连接 url 正确,测试按预期进行。