spring-bootspring-data-jpaspring-boot-jpa

Exclude certain DataSource(s) from HibernateJpaAutoConfiguration


I have a project with 2 DataSources. One is for PostgreSQL and other is for ClickHouse. No problem so far.

I intend to use ClickHouse with native SQL via JDBC only.

But I would like to use JPA based repositories with PostgreSQL datasource. And if I add spring-boot-starter-data-jpa dependency, HibernateJpaAutoConfiguration kicks in for ALL registered DataSource beans. ClickHouse is not a transactional relational DB and its JDBC implementation is very limited and basic, never intended for use with Hibernate. So my question is: is it possible to use DataSourceAutoConfiguration for both datasources, but somehow tell HibernateJpaAutoConfiguration to configure just with PostgreSQL datasource?

I would still like to use auto configuration goodies like DataSource configuration with Connection pooling with practically just a few lines in properties file. I know I can exclude HibernateJpaAutoConfiguration completely and configure everything (entityManager, transactionManager, ...) on my own, but I would like to avoid that if possible. Just telling it to avoid configuring ClickHouse datasource seems way more elegant.


Update

Some of my assumptions were incorrect. Read the accepted answer. It is very insightful.


Solution

  • DataSourceAutoConfiguration will only kick in if you do not define any beans for the datasource .It will then create and configure only one datasource based on the setting configured in the application.properties. That means if you need to create two datasources ,it cannot be used for such case and you have to manually define both datasources. You can refer to the docs for how to configure multiple datasources by simulating what are done by the DataSourceAutoConfiguration.

    On the other hand, HibernateJpaAutoConfiguration will only kick in if there is only one Datasource bean defined (see the codes as it is marked with @ConditionalOnSingleCandidate)

    And from the javadoc of @ConditionalOnSingleCandidate:

    @Conditional that only matches when a bean of the specified class is already contained in the BeanFactory and a single candidate can be determined.

    The condition will also match if multiple matching bean instances are already contained in the BeanFactory but a primary candidate has been defined; essentially, the condition match if auto-wiring a bean with the defined type will succeed.

    That mean you can simply mark the DataSource bean that you define for the PostgreSQL with @Primary and HibernateJpaAutoConfiguration should only consider it but ignore others.