Hello, this is an enhancement suggestion (which I'm happy to implement as well but wanted to make sure there's not a good reason that it was not done before prior to working on it).

As part of https://github.com/spring-projects/spring-boot/issues/9218, the DataSourceClosingSpringLiquibase class was added. This allows closing the connection pool once the liquibase migrations are applied (in case of Liquibase being ran on application startup mostly) instead of hanging around for the whole application lifecycle.

Unfortunately it is only auto-configured (instead of the standard SpringLiquibase) if no DataSource has been configured with @LiquibaseDataSource annotated on it, as that datasource would be autowired here: https://github.com/spring-projects/spring-boot/blob/a6f8351dd64ec288424ceb5bc6e4505e00c7d5a2/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfiguration.java#L82-L90

and yield the "standard" branch here:

https://github.com/spring-projects/spring-boot/blob/a6f8351dd64ec288424ceb5bc6e4505e00c7d5a2/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/liquibase/LiquibaseAutoConfiguration.java#L118-L129

The proposal is to allow forcing DataSourceClosingSpringLiquibase through a property of LiquibaseProperties.

Probably something like closeDataSourceOnceMigrated as it's already named in DataSourceClosingSpringLiquibase itself right now and overriden in LiquibaseEndpointAutoConfiguration#preventDataSourceCloseBeanPostProcessor if the Liquibase endpoint is enabled.

As for the motivation, it would allow more customization of the underlying DataSource used. So we could set hikari-level configuration that is specific to the Liquibase pool, (pool name, max pool size... and other such things as we already do for other DataSource instances) without having to share it with other "post-initialization" datasources.

Thank you

Comment From: Tristan971

Hello, Just chiming in to know if you have not had time to look at it yet or are discussing it internally? Or should I make a PR to show how the general idea would work? Thanks 🙂

Comment From: wilkinsona

Sorry, @Tristan971. We've discussed this and have been meaning to follow up. Rather than using a property that is bound to LiquibaseProperties, we think it might be better to add an attribute to the @LiquibaseDataSource annotation. If you'd like to prepare a pull request in that direction we would be more than happy to review it. It may be a little bit tricky to get the definition for the @LiquibaseDataSource bean to retrieve the annotation and its attribute but we think it should be possible.

Comment From: Tristan971

Seems like a good compromise ; I'll get a PR ready for it soon-ish :-)

Comment From: Tristan971

Alright I got something, and indeed, It may be a little bit tricky proved to be its own little adventure :slightly_smiling_face:

Comment From: philwebb

Closing in favor of PR #18240

Comment From: snicoll

We've discussed this one at the team meeting and having an option to close a DataSource that is exposed as a @Bean by the user feels a bit odd. When an object is exposed as a @Bean there is an implicit lifecycle semantic attached to it (in particular that it's going to be closed/disposed when the application stops).

Taking a step back, it looks like @LiquibaseDatasource is used because a specific DataSource has to be created and what spring.liquibase offers in terms of configuring a DataSource for the purpose of the migration is too limited. We'd like to explore an option where you have a chance to supply the DataSource to use.

We have currently some logic to check for a @LiquibaseDataSource qualified datasource or, alternatively, a single DataSource candidate from the context. We could extract that logic in the supplier with the ability for the user to replace it. Providing their own implementation would let them create whatever DataSource they need. It's not clear yet how the return type would indicate that it should be closed once the migration has completed.

I've also considered streamlining that with a generic DataSourceProvider. I've hacked some code on a branch: https://github.com/snicoll/spring-boot/commit/f7d4cbf0b72268b4aaad07fff2ffc5315300b9e4

Comment From: Tristan971

having an option to close a DataSource that is exposed as a @Bean by the user feels a bit odd

Fair point indeed

We'd like to explore an option where you have a chance to supply the DataSource to use

That was actually what I needed, and this issue was because I couldn't do that ; so I'd be very happy with that as well

I've hacked some code on a branch: snicoll@f7d4cbf

It seems like a good way forward!

The ideal flow with this would seem to be: - define liquibase to be closing (somewhere in LiquibaseProperties seems like it to me) - when liquibase starts, it gets a DS from the DSP (via getInitializationDataSource), then closes the DS - app gets another DS from the DSP (through getDataSource) and does whatever it must

To give a bit more context, the basic need was to have a different DB user perform the migration from the one the app uses afterwards. We also needed it to close to not unnecessarily hold connections.

Comment From: snicoll

Thanks for the context @Tristan971

To give a bit more context, the basic need was to have a different DB user perform the migration from the one the app uses afterwards

If that's all you need you could configure the Datasource to use for the migration using spring.liquibase.* properties. It would allow you to create a datasource for the duration of the migration with a different user, something like:

spring.liquibase.url=jdbc:postgresql://host/db_to_migrate
spring.liquibase.user=different-user
spring.liquibase.password=secret

Give you've implemented something specific, I am guessing there's more to it and I am missing something. It would be nice to know what the actual need was if you can share.

Comment From: Tristan971

Thanks for taking the time @snicoll :slightly_smiling_face:

That does indeed work (and actually is what we went with in the meantime)

However it has a few limitations: - You are kind of forced to use the .properties based configuration (or give up 99% of the config you get for free with the LiquibaseAutoConfiguration, and redeclare almost every bean yourself), or give up on auto-closing - You can't have different spring.datasource.* configurations for the Liquibase and the "normal" one - it will seem silly, but what sparked this was thinking it'd be fancy to have different pool names, for logs/monitoring clarity (xyz-liquibase-pool and xyz-pool)

At the end of the day, none of this is impossible to live with, but it just feels slightly arbitrary of a limitation and causes a few small problems that would just go away with something like the DataSourceProvider you mentionned.