У меня есть две базы данных: MySQL и Clickhouse.
Я создал две отдельные конфигурации для обеих БД:
для MySQL (он первичен):
@EnableJpaRepositories(
entityManagerFactoryRef = "mysqlEM",
basePackages = {"com.myproject.repository.mysqlrepos"})
@Configuration(proxyBeanMethods = false)
public class MySQLDatasourceConfiguration {
@Bean
@Primary
@ConfigurationProperties("spring.datasource.mysql")
public DataSourceProperties mysqlDbProperties() {
return new DataSourceProperties();
}
@Bean
@Primary
@ConfigurationProperties("spring.datasource.mysql.hikari")
public HikariDataSource mysqlDataSource(
DataSourceProperties mysqlDbProperties) {
return mysqlDbProperties
.initializeDataSourceBuilder()
.type(HikariDataSource.class)
.build();
}
@Bean(name = "mysqlEM")
@Primary
public LocalContainerEntityManagerFactoryBean mysqlEntityManagerFactory(
EntityManagerFactoryBuilder builder, DataSource mysqlDataSource) {
HashMap<String, Object> properties = new HashMap<>();
return builder.dataSource(mysqlDataSource)
.properties(properties)
.packages("com.myproject.entity.mysqlentities")
.persistenceUnit("mysql")
.build();
}
}
для Кликхауса:
@EnableJpaRepositories(
entityManagerFactoryRef = "clickhouseEM",
basePackages = {"com.myproject.repository.clickhouserepos"})
@Configuration(proxyBeanMethods = false)
public class ClickhouseDatasourceConfiguration {
@Bean
@ConfigurationProperties("spring.datasource.clickhouse")
public DataSourceProperties clickhouseDbProperties() {
return new DataSourceProperties();
}
@Bean
@ConfigurationProperties("spring.datasource.clickhouse.hikari")
public HikariDataSource clickhouseDataSource(
DataSourceProperties clickhouseDbProperties) {
return clickhouseDbProperties
.initializeDataSourceBuilder()
.type(HikariDataSource.class)
.build();
}
@Bean(name = "clickhouseEM")
public LocalContainerEntityManagerFactoryBean clickhouseEntityManagerFactory(
EntityManagerFactoryBuilder builder, DataSource clickhouseDataSource) {
HashMap<String, Object> properties = new HashMap<>();
return builder.dataSource(clickhouseDataSource)
.properties(properties)
.packages("com.myproject.entity.clickhouseentities")
.persistenceUnit("clickhouse")
.build();
}
}
Все репозитории MySQL расширяются JPARepository
.
Однако для Clickhouse я создал собственный репозиторий с одним единственным методом для запуска собственного запроса «выбрать» к Clickhouse.
Это интерфейс репозитория:
@Repository
public interface MyClickhouseRepository {
List<MyClickhouseEntity> findSomeoneInClickhouse(String name);
}
И это его реализация:
@Repository
public class MyClickhouseRepositoryImpl implements MyClickhouseRepository {
@Autowired
@Qualifier("clickhouseEM") EntityManager em;
@Override
public List<MyClickhouseEntity> findSomeoneInClickhouse(String name) {
Query query = em.createNativeQuery("select * from myschema.mytable final where name = :name", MyClickhouseEntity.class);
query.setParameter("name", name);
List<MyClickhouseEntity> res = query.getResultList();
return res;
}
}
Приложение запускается успешно, но когда я вызываю метод findSomeoneInClickhouse(String)
MyClickhouseRepositoryImpl
, оно выдает ошибку:
Caused by: java.sql.SQLSyntaxErrorException: Unknown database 'myschema'
, но эта база данных существует в Clickhouse.
И если я запускаю запрос, содержащий ключевые слова, специфичные для Clickhouse, он выдает ошибку:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use
Обе эти ошибки показывают, что мое приложение запрашивает только MySQL и не использует Clickhouse, хотя я использую clickhouseEM
менеджер сущностей в репозитории.
Если я удалю аннотации @Primary
из конфигурации MySQL и добавлю их в конфигурацию Clickhouse, все будет наоборот — мое приложение запрашивает только Clickhouse и не использует MySQL.
Есть идеи, что мне здесь не хватает?
Кажется, что DataSourceProperties
, введенный в методы источника данных, и есть @Primary
. Убедитесь, что DataSourceProperties
, введенные в методы источника данных, подходят для каждого источника данных, используя аннотацию @Qualifier
:
@Bean
@Primary
@ConfigurationProperties("spring.datasource.mysql.hikari")
public HikariDataSource mysqlDataSource(
@Qualifier("mysqlDbProperties") DataSourceProperties mysqlDbProperties) {
return mysqlDbProperties
.initializeDataSourceBuilder()
.type(HikariDataSource.class)
.build();
}
@Bean
@ConfigurationProperties("spring.datasource.clickhouse.hikari")
public HikariDataSource clickhouseDataSource(
@Qualifier("clickhouseDbProperties") DataSourceProperties clickhouseDbProperties) {
return clickhouseDbProperties
.initializeDataSourceBuilder()
.type(HikariDataSource.class)
.build();
}
Я также считаю, что аннотация @ConfigurationProperties
к методам источника данных не нужна и ее можно удалить.
спасибо, что ответили на мой вопрос, это действительно произошло из-за отсутствия
@Qualifier
аннотаций. Я как-то забыл, что бины определяются по именам, а не по типам. Таким образом, оба менеджера организаций использовали один и тот же основнойHikariDataSource