Last active
August 15, 2024 07:34
-
-
Save dakoctba/1047ca084118ff46a1a917726f99a2b2 to your computer and use it in GitHub Desktop.
Spring Boot + JDBI + Multiple Databases
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.List; | |
import javax.sql.DataSource; | |
import org.jdbi.v3.core.Jdbi; | |
import org.jdbi.v3.core.mapper.RowMapper; | |
import org.jdbi.v3.core.spi.JdbiPlugin; | |
import org.jdbi.v3.sqlobject.SqlObjectPlugin; | |
import org.springframework.beans.factory.annotation.Qualifier; | |
import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer; | |
import org.springframework.context.annotation.Bean; | |
import org.springframework.context.annotation.Configuration; | |
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy; | |
import br.com.company.produto.dao.dominio.CityDAO; | |
import br.com.company.produto.dao.dw.ProfessionDAO; | |
@Configuration | |
public class AppConfig { | |
@Bean("jdbi-1") | |
public Jdbi jdbi(@Qualifier("datasource1") DataSource ds, List<JdbiPlugin> plugins, List<RowMapper<?>> mappers) { | |
TransactionAwareDataSourceProxy proxy = new TransactionAwareDataSourceProxy(ds); | |
Jdbi jdbi = Jdbi.create(proxy); | |
plugins.forEach(plugin -> jdbi.installPlugin(plugin)); | |
mappers.forEach(mapper -> jdbi.registerRowMapper(mapper)); | |
return jdbi; | |
} | |
@Bean("jdbi-2") | |
public Jdbi secondaryJdbi(@Qualifier("datasource2") DataSource ds, List<JdbiPlugin> plugins, List<RowMapper<?>> mappers) { | |
TransactionAwareDataSourceProxy proxy = new TransactionAwareDataSourceProxy(ds); | |
Jdbi jdbi = Jdbi.create(proxy); | |
plugins.forEach(plugin -> jdbi.installPlugin(plugin)); | |
mappers.forEach(mapper -> jdbi.registerRowMapper(mapper)); | |
return jdbi; | |
} | |
@Bean | |
public JdbiPlugin sqlObjectPlugin() { | |
return new SqlObjectPlugin(); | |
} | |
@Bean | |
public CityDAO cityDao(@Qualifier("jdbi-1") Jdbi jdbi) { | |
return jdbi.onDemand(CityDAO.class); | |
} | |
@Bean | |
public ProfessionDAO professionDao(@Qualifier("jdbi-2") Jdbi jdbi) { | |
return jdbi.onDemand(ProfessionDAO.class); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect | |
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false | |
spring.jpa.database=default | |
# | |
# Primary database | |
# | |
spring.datasource.db1.jdbcUrl=jdbc:postgresql://localhost:5432/<database> | |
spring.datasource.db1.driver-class-name=org.postgresql.Driver | |
spring.datasource.db1.username=postgres | |
spring.datasource.db1.password=postgres | |
# | |
# Secondary database | |
# | |
spring.datasource.db2.jdbcUrl=jdbc:postgresql://localhost:5432/<database> | |
spring.datasource.db2.driver-class-name=org.postgresql.Driver | |
spring.datasource.db2.username=postgres | |
spring.datasource.db2.password=postgres |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import javax.sql.DataSource; | |
import org.springframework.beans.factory.annotation.Autowired; | |
import org.springframework.beans.factory.annotation.Qualifier; | |
import org.springframework.boot.context.properties.ConfigurationProperties; | |
import org.springframework.boot.jdbc.DataSourceBuilder; | |
import org.springframework.context.annotation.Bean; | |
import org.springframework.context.annotation.Configuration; | |
import org.springframework.context.annotation.Primary; | |
import org.springframework.jdbc.datasource.DataSourceTransactionManager; | |
@Configuration | |
public class DataSourceConfig { | |
@Bean(name = "datasource1") | |
@ConfigurationProperties("spring.datasource.db1") | |
@Primary | |
public DataSource db1Datasource() { | |
return DataSourceBuilder.create().build(); | |
} | |
@Bean(name = "datasource2") | |
@ConfigurationProperties("spring.datasource.db2") | |
public DataSource db2Datasource() { | |
return DataSourceBuilder.create().build(); | |
} | |
@Bean(name="tm1") | |
@Autowired | |
@Primary | |
DataSourceTransactionManager tm1(@Qualifier ("datasource1") DataSource datasource) { | |
DataSourceTransactionManager txm = new DataSourceTransactionManager(datasource); | |
return txm; | |
} | |
@Bean(name="tm2") | |
@Autowired | |
DataSourceTransactionManager tm2(@Qualifier ("datasource2") DataSource datasource) { | |
DataSourceTransactionManager txm = new DataSourceTransactionManager(datasource); | |
return txm; | |
} | |
} |
can you explain for what the DataSourceTransactionManager
Bean is required for?
From my experience it's enough to use TransactionAwareDataSourceProxy
to make springs @Transactional
annotation working with jdbi.
Also according to the jdbi documention you should use Spring SpringConnectionFactory
instead TransactionAwareDataSourceProxy
to create a JDBI
bean instance.
see: https://jdbi.org/#_annotation_based_configuration
@Configuration
public class JdbiConfiguration {
@Bean
public Jdbi jdbi(DataSource ds) {
ConnectionFactory cf = new SpringConnectionFactory(dataSource);
final Jdbi jdbi = Jdbi.create(cf);
/* additional configuration goes here */
return jdbi;
}
}
This code doesn't run for me cuz of exception
No qualifying bean of type 'org.jdbi.v3.core.Jdbi' available: expected single matching bean but found 2: jdbi-1,jdbi-2
But it fixes by annotating with @primary for some of jdbi Bean, e.g.:
@Bean(value = "jdbi-1")
@Primary
public Jdbi jdbi()
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Nice!!