Java 在Spring中初始化多个数据库
我使用AbstractRoutingDatasource在运行时在数据库之间进行路由。在informix数据库的实际情况下,一切正常 对于测试,我创建了一个spring概要文件,以在内存H2数据库中使用。 运行带有测试概要文件的spring应用程序后,我使用h2控制台检查了本地数据库。未创建任何架构 我尝试在资源和休眠中使用schema.sql:Java 在Spring中初始化多个数据库,java,database,spring,hibernate,spring-boot,Java,Database,Spring,Hibernate,Spring Boot,我使用AbstractRoutingDatasource在运行时在数据库之间进行路由。在informix数据库的实际情况下,一切正常 对于测试,我创建了一个spring概要文件,以在内存H2数据库中使用。 运行带有测试概要文件的spring应用程序后,我使用h2控制台检查了本地数据库。未创建任何架构 我尝试在资源和休眠中使用schema.sql: generate-ddl: true hibernate: ddl-auto: create-drop 冬眠投掷 java.lang.Illeg
generate-ddl: true
hibernate:
ddl-auto: create-drop
冬眠投掷
java.lang.IllegalStateException: Cannot determine target DataSource for lookup key [null]
据我所知,hibernate试图只生成“路由”数据源。由于未设置DatabaseContextHolder(null),因此此操作失败
所以这两种方法都失败了
有没有办法用(相同)模式初始化所有数据库
我在下面列出了我的配置
bootstrap.yml:
spring:
profiles: acceptanceTest
config:
name: standalone
cloud:
config:
enabled: false
discovery:
enabled: false
jpa:
database-platform: org.hibernate.dialect.H2Dialect
generate-ddl: true
hibernate:
ddl-auto: create-drop
properties:
hibernate:
show_sql: false
use_sql_comments: false
format_sql: false
h2:
console:
enabled: true
path: /h2
datasource:
mc:
driver-class-name: 'org.h2.Driver'
url: 'jdbc:h2:mem:test-mc-db;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE'
username: sa
password: ''
platform: h2
initialize: true
type: com.zaxxer.hikari.HikariDataSource
hikari:
maximum-pool-size: 10
minimum-idle: 0
idle-timeout: 60000
pool-name: MarkHikariPool
cw:
driver-class-name: 'org.h2.Driver'
url: 'jdbc:h2:mem:test-cw-db'
username: sa
password: ''
type: com.zaxxer.hikari.HikariDataSource
hikari:
maximum-pool-size: 10
minimum-idle: 0
idle-timeout: 60000
pool-name: MarkHikariPool
MainApp.java:
@ComponentScan({ "de.md.mark" })
@EnableDiscoveryClient
@SpringBootApplication(
exclude =
{
DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class,
HibernateJpaAutoConfiguration.class
}
)
public class MainApp
{
public static void main(String[] args)
{
DataSourceConfiguration.java:
@Configuration
@EnableJpaRepositories(
basePackageClasses = { MarkTypeRepository.class, MarkRepository.class }, entityManagerFactoryRef = "markEntityManager",
transactionManagerRef = "markTransactionManager"
)
@EnableTransactionManagement
public class DataSourceConfiguration
{
@Autowired(required = false)
private PersistenceUnitManager persistenceUnitManager;
@Bean
@ConfigurationProperties("app.jpa")
@Primary
public JpaProperties jpaProperties()
{
return new JpaProperties();
}
@Bean
@ConfigurationProperties(prefix = "datasource.mc")
public DataSource mcDataSource()
{
return DataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties(prefix = "datasource.cw")
public DataSource cwDataSource()
{
return DataSourceBuilder.create().build();
}
@Bean
@Primary
public DataSource dataSource()
{
DataSourceRouter router = new DataSourceRouter();
final HashMap<Object, Object> map = new HashMap<>(DatabaseEnvironment.values().length);
map.put(DatabaseEnvironment.MC, mcDataSource());
map.put(DatabaseEnvironment.CW, cwDataSource());
router.setTargetDataSources(map);
return router;
}
@Bean
@Primary
public LocalContainerEntityManagerFactoryBean markEntityManager(final JpaProperties jpaProperties)
{
EntityManagerFactoryBuilder builder = createEntityManagerFactoryBuilder(jpaProperties);
return builder.dataSource(dataSource()).packages(MarkTypeEntity.class).persistenceUnit("markEntityManager").build();
}
@Bean
@Primary
public JpaTransactionManager markTransactionManager(@Qualifier("markEntityManager") final EntityManagerFactory factory)
{
return new JpaTransactionManager(factory);
}
private EntityManagerFactoryBuilder createEntityManagerFactoryBuilder(JpaProperties jpaProperties)
{
JpaVendorAdapter jpaVendorAdapter = createJpaVendorAdapter(jpaProperties);
return new EntityManagerFactoryBuilder(jpaVendorAdapter, jpaProperties.getProperties(), this.persistenceUnitManager);
}
private JpaVendorAdapter createJpaVendorAdapter(JpaProperties jpaProperties)
{
AbstractJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
adapter.setShowSql(jpaProperties.isShowSql());
adapter.setDatabase(jpaProperties.getDatabase());
adapter.setDatabasePlatform(jpaProperties.getDatabasePlatform());
adapter.setGenerateDdl(jpaProperties.isGenerateDdl());
return adapter;
}
}
@配置
@授权代理(
basePackageClasses={MarkTypeRepository.class,MarkRepository.class},entityManagerFactoryRef=“markEntityManager”,
transactionManagerRef=“markTransactionManager”
)
@启用事务管理
公共类数据源配置
{
@自动连线(必需=错误)
私有PersistenceUnitManager PersistenceUnitManager;
@豆子
@ConfigurationProperties(“app.jpa”)
@初级的
公共JPA物业JPA物业()
{
返回新的JPA属性();
}
@豆子
@ConfigurationProperties(前缀=“datasource.mc”)
公共数据源mcDataSource()
{
返回DataSourceBuilder.create().build();
}
@豆子
@ConfigurationProperties(前缀=“datasource.cw”)
公共数据源cwDataSource()
{
返回DataSourceBuilder.create().build();
}
@豆子
@初级的
公共数据源数据源()
{
DataSourceOuter路由器=新DataSourceOuter();
final HashMap map=新HashMap(DatabaseEnvironment.values().length);
put(DatabaseEnvironment.MC,mcDataSource());
put(DatabaseEnvironment.CW,cwDataSource());
路由器。setTargetDataSources(map);
返回路由器;
}
@豆子
@初级的
public LocalContainerEntityManagerFactoryBean markEntityManager(最终JPA属性JPA属性)
{
EntityManagerFactoryBuilder=createEntityManagerFactoryBuilder(JPA属性);
返回builder.dataSource(dataSource()).packages(MarkTypeEntity.class).persistenceUnit(“markEntityManager”).build();
}
@豆子
@初级的
公共JpaTransactionManager markTransactionManager(@Qualifier(“markEntityManager”)最终EntityManager工厂)
{
返回新的JpaTransactionManager(工厂);
}
私有EntityManagerFactoryBuilder createEntityManagerFactoryBuilder(JPAPProperties JPAPProperties)
{
JpaVendorAdapter-JpaVendorAdapter=createJpaVendorAdapter(jpapproperties);
返回新的EntityManagerFactoryBuilder(jpaVendorAdapter,jpapProperties.getProperties(),this.persistenceUnitManager);
}
专用JpaVendorAdapter createJpaVendorAdapter(JPAPProperties JPAPProperties)
{
AbstractJpaVendorAdapter=新的HibernateJpaVendorAdapter();
setShowSql(jpaProperties.isShowSql());
setDatabase(jpapProperties.getDatabase());
setDatabasePlatform(jpapProperties.getDatabasePlatform());
setGenerateDdl(jpapProperties.isGenerateDdl());
返回适配器;
}
}
在过去两天的大量研究之后,我找到了一个初始化所有数据源的解决方案。
我使用hibernate的SchemaExport.class创建了一个方法来创建和初始化本地H2数据库。
因为我只需要本地db进行测试,所以我在@Before cumber方法中为每个DatabaseEnvirement调用该方法
public void createDatabase(DatabaseEnvironment environment)
throws Exception
{
// load hibernate configuration from hibernate.cfg.xml in classpath
Configuration configuration = new Configuration().configure();
MetadataSources metadata =
new MetadataSources(new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build());
ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(true);
scanner.addIncludeFilter(new AnnotationTypeFilter(Entity.class));
for (BeanDefinition def : scanner.findCandidateComponents(MarkEntity.class.getPackage().getName()))
{
metadata.addAnnotatedClass(Class.forName(def.getBeanClassName()));
}
Connection connection = DriverManager.getConnection("jdbc:h2:mem:test-" + environment.name().toLowerCase(), "sa", "");
SchemaExport export = new SchemaExport((MetadataImplementor) metadata.buildMetadata(), connection);
export.create(true, true);
}
@Before
public void beforeTest()
throws Exception
{
// initialise databases
for (DatabaseEnvironment env : DatabaseEnvironment.values())
{
createDatabase(env);
}
}
下面是我的hibernate.cfg.xml的样子:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="dialect">org.hibernate.dialect.H2Dialect</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">create-drop</property>
</session-factory>
</hibernate-configuration>
org.hibernate.dial.h2方言
真的
创建下降