Spring Repository – невозможно использовать два источника данных для MySQL и Clickhouse

У меня есть две базы данных: 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.

Есть идеи, что мне здесь не хватает?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
139
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Кажется, что 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

mangusta 07.04.2024 00:17

Другие вопросы по теме