Using Spring Boot 2.0.2.RELEASE I set up a simple project that uses Flyway for migrations and JDBC template for accessing the DB. I expect all Flyway migrations to finish running before I can use the datasource. However, I noticed that PostConstruct runs before Flyway migrations. That means I access the old version of the schema, causing application failures.

As mentioned here, one may annotate the component that uses JdbcTemplate with: @DependsOn({"flyway", "flywayInitializer"}), but this is cumbersome and error prone - it is easy to forget to do so, and I don't see a reason this shouldn't be the default behaviour.

The attached project is a minimal Spring Boot application with a single component that uses the database in its PostConstruct method. The output shows that PostConstruct is called before Flyway runs.

demo-4.zip

Comment From: MatanRubin

Furthermore, even if I change the PostConstruct method to an EventListener that handles onApplicationReady events, the same behaviour persists. Unless I'm missing something, Flyway should definitely finish running before an ApplicationReady event happens. What am I missing?

Comment From: snicoll

What am I missing?

I don't know but it definitely runs as part of the InitializingBean callback (i.e. before that event is triggered).

As for your initial request, I think what we have right now is consistent with many other features. If you use @Transactional for instance, you can't use them as part of the @PostConstruct callback and you should use TransactionTemplate. Same things for caching. See also this section in the Spring Framework ref guide. Using the event is the right way of doing this (or you may way want to implement SmartInitializingSingleton).

Can you please share a sample that demonstrates that Flyway is not called when that event is fired?

Comment From: MatanRubin

Please ignore my comment regarding onApplicationReady - I checked it again and it works well.

Regarding @PostConstruct, I disagree that this is consistent behaviour. Developers expect that once a bean is initialized, all its dependent beans are initialized. Flyway is not a piece of application code - it is an infrastructure tool that helps initialize the database - I don't see a use case where you want to use the old schema version in a @PostConstruct and then have Flyway run and change your schema.

Comment From: snicoll

I disagree that this is consistent behaviour.

That's not what I wrote. Please look at the link and the explanation again.

Developers expect that once a bean is initialized, all its dependent beans are initialized.

You don't have a dependency on Flyway, you have a dependency on a DataSource. I agree that it would be nicer if that was taken care for you. We have a similar request for another component and I think we could use that work to fix this problem as well.

Comment From: wilkinsona

This feels like a bug to me. If you consume the auto-configured JdbcTemplate (as is being done here), I think it's reasonable to expect that the underlying DataSource will have been initialized before you're given a chance to use the template. This situation is analogous to doing something with JPA. In that case we do ensure that any Flyway migrations have occurred before you can do anything with the database.

Comment From: nameof

I have also been confused about this. If this is consistent with other features, please provide at least the corresponding instructions in the spring boot documentation.

Comment From: wilkinsona

@nameof Please read my comment that is immeadiately before yours. It’s a bug that we intend to fix.

Comment From: nameof

@wilkinsona got it , really sorry for this

Comment From: jordanms

We have the same problem with 2.2.4.RELEASE. Wasn't this supposed to be fixed?

Comment From: philwebb

@jordanms This issue should have been fixed for quite some time. If you're facing a similar problem, please open a new issue and provide a small sample application that demonstrates it.

Comment From: jordanms

@philwebb I created the new issue with sample code: https://github.com/spring-projects/spring-boot/issues/21436