Ich musste auch eine Verbindung zu 2 Datenquellen aus der Spring Boot-Anwendung herstellen, und es war nicht einfach - die in der Spring Boot-Dokumentation erwähnte Lösung funktionierte nicht. Nach langem Stöbern im Internet habe ich es zum Laufen gebracht und die Hauptidee wurde aus diesem Artikel und vielen anderen Orten übernommen.
Die folgende Lösung ist in geschrieben Kotlin geschrieben und funktioniert mit Spring Boot 2.1.3 und Hibernate Core 5.3.7 . Das Hauptproblem war, dass es nicht ausreichte, nur verschiedene DataSource- Konfigurationen einzurichten, sondern auch EntityManagerFactory und TransactionManager für beide Datenbanken zu konfigurieren .
Hier ist die Konfiguration für die erste (primäre) Datenbank:
@Configuration
@EnableJpaRepositories(
entityManagerFactoryRef = "firstDbEntityManagerFactory",
transactionManagerRef = "firstDbTransactionManager",
basePackages = ["org.path.to.firstDb.domain"]
)
@EnableTransactionManagement
class FirstDbConfig {
@Bean
@Primary
@ConfigurationProperties(prefix = "spring.datasource.firstDb")
fun firstDbDataSource(): DataSource {
return DataSourceBuilder.create().build()
}
@Primary
@Bean(name = ["firstDbEntityManagerFactory"])
fun firstDbEntityManagerFactory(
builder: EntityManagerFactoryBuilder,
@Qualifier("firstDbDataSource") dataSource: DataSource
): LocalContainerEntityManagerFactoryBean {
return builder
.dataSource(dataSource)
.packages(SomeEntity::class.java)
.persistenceUnit("firstDb")
// Following is the optional configuration for naming strategy
.properties(
singletonMap(
"hibernate.naming.physical-strategy",
"org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl"
)
)
.build()
}
@Primary
@Bean(name = ["firstDbTransactionManager"])
fun firstDbTransactionManager(
@Qualifier("firstDbEntityManagerFactory") firstDbEntityManagerFactory: EntityManagerFactory
): PlatformTransactionManager {
return JpaTransactionManager(firstDbEntityManagerFactory)
}
}
Und das ist die Konfiguration für die zweite Datenbank:
@Configuration
@EnableJpaRepositories(
entityManagerFactoryRef = "secondDbEntityManagerFactory",
transactionManagerRef = "secondDbTransactionManager",
basePackages = ["org.path.to.secondDb.domain"]
)
@EnableTransactionManagement
class SecondDbConfig {
@Bean
@ConfigurationProperties("spring.datasource.secondDb")
fun secondDbDataSource(): DataSource {
return DataSourceBuilder.create().build()
}
@Bean(name = ["secondDbEntityManagerFactory"])
fun secondDbEntityManagerFactory(
builder: EntityManagerFactoryBuilder,
@Qualifier("secondDbDataSource") dataSource: DataSource
): LocalContainerEntityManagerFactoryBean {
return builder
.dataSource(dataSource)
.packages(EntityFromSecondDb::class.java)
.persistenceUnit("secondDb")
.build()
}
@Bean(name = ["secondDbTransactionManager"])
fun secondDbTransactionManager(
@Qualifier("secondDbEntityManagerFactory") secondDbEntityManagerFactory: EntityManagerFactory
): PlatformTransactionManager {
return JpaTransactionManager(secondDbEntityManagerFactory)
}
}
Die Eigenschaften für Datenquellen lauten wie folgt:
spring.datasource.firstDb.jdbc-url=
spring.datasource.firstDb.username=
spring.datasource.firstDb.password=
spring.datasource.secondDb.jdbc-url=
spring.datasource.secondDb.username=
spring.datasource.secondDb.password=
Das Problem mit den Eigenschaften war, dass ich jdbc-url anstelle von url definieren musste, da ich sonst eine Ausnahme hatte.
ps
Möglicherweise haben Sie auch unterschiedliche Namensschemata in Ihren Datenbanken, was bei mir der Fall war. Da Hibernate 5 nicht alle vorherigen Namensschemata unterstützt, musste ich eine Lösung aus dieser Antwort verwenden - vielleicht hilft es auch jemandem.