26

I am using Maven and Spring Boot. I run the application using mvn spring-boot:run.

https://flywaydb.org/documentation/plugins/springboot says Flyway should be called on Spring Boot start.

So my pom.xml contains the dependency to Flyway.

<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-core</artifactId>
    <version>4.1.2</version>
</dependency>

The first time I ran the Maven command above it downloaded Flyway stuff, so I think the dependency is working.

I have the following files:

./src/main/resources/db/migration/V123__foo.sql
./src/main/resources/application.properties

The above article implied it should "just work", but I don't understand where it would find the JDBC URL to the database. So I added the following to the application.properties file:

flyway.url=jdbc:postgresql://localhost:5432/services?user=postgres&password=postgres
flyway.enabled=true

When Spring Boot starts up (and loads and makes available my web application) there are no logs from Flyway. I think Flyway is ignored.

What can I do? Or, more generally, how would I go about debugging this problem myself?

Adrian Smith
  • 17,236
  • 11
  • 71
  • 93
  • 2
    flyway will by default use the normal datasource specified by `spring.datasource` properties generally you don't need an additional one. If you really want to use separate URL and user for flyway you need `flyway.url` with `flyway.username` and `flyway.password` and not embedded in the URL. Next to that make sure you have a database driver else no JDBC is detected and nothing will be run (without JDBC it won't work). – M. Deinum Apr 19 '17 at 13:06
  • Thanks for the advice. There are no errors though, the application "runs" (just without Flyway being called), I suspect (hope?) that if the data source was wrong (e.g. no JDBC driver) then it would print an error, or am I wrong in that assumption? – Adrian Smith Apr 19 '17 at 13:20
  • If you are already using a datasource then that will be used by default. Also what do you expect to see? Logging depends on your loglevel if that is high (WARN or something) you won't see a thing. Instead of relying on logging you might want to check the content of your database instead. – M. Deinum Apr 19 '17 at 13:24
  • I am not currently using a datasource (it's a new project). According to https://docs.spring.io/spring-boot/docs/current/reference/html/howto-database-initialization.html "Or you can use Flyway’s native DataSource by setting flyway.[url,user,password] in external properties." So setting flyway.xx properties and running the Spring Boot application not only doesn't log, it also doesn't affect the database. (If I use Maven's Flyway plugin, to migrate during build, then the database is migrated, so I think the migration files are i the right place. But I want on Spring Boot startup) – Adrian Smith Apr 19 '17 at 13:42
  • 1
    As I stated in my first comment if will only work if you are using a datasource already. If you aren't it doesn't do anything. The flyway configuration depends on the availability of a datasource. If that isn't availing flyway will be disabled. – M. Deinum Apr 19 '17 at 14:14
  • Thanks, that's the conclusion I've come to as well. However that's not what the documentation says. Thanks for your advice! – Adrian Smith Apr 19 '17 at 14:27
  • @M.Deinum In [my case](https://stackoverflow.com/questions/50205340/flywaydb-migration-scripts-not-getting-executed) I am using a datascource. I'm not setting it explicitly but via my `application.properties`. However, none if my migration scripts are getting executed. Any idea? – Stefan Falk May 06 '18 at 23:31

1 Answers1

33

Nobody has posted an answer so I'll post what I found out.

M. Deinum was indeed correct in their comments to the question, the problem was a lack of a data source.

My original question was what the approach should be to debugging this kind of issue. Obviously one option is to post to stackoverflow :) But I wanted to know how to do it myself.

Spring Boot has a number of classes which look at your code and classpath, and act appropriately. For example, there are classes providing implementations to the rules like "if Flyway is on the path, and there is a data source, then execute Flyway". That rule wasn't getting triggered in my case, because I had no data source.

It's not the case that the code you write calls Spring Boot, it's the other way around, Spring Boot (external to your code) inspects your code and decides what to do based on rules. This architecture is known as action at a distance. The main problem with action at a distance is it's very difficult to debug.

The only real way to find the solution, and it was the way I went about confirming M. Deinum's diagnostic, is to read the Spring Boot source code and understand the annotations which are used to create Spring Boot code.

From the source code to Spring Boot's Flyway integration we see

@ConditionalOnClass(Flyway.class)
@ConditionalOnBean(DataSource.class)

This means "this code will get executed if Flyway is on the classpath, and if there is a DataSource bean available; otherwise it silently won't get executed".

So the answer to the question "how to debug this problem" is that there is no mechanism other than to read the source code of Spring Boot and find out how it works.

If you want to avoid this sort of problem, you have to avoid frameworks which work via "action at a distance", and that includes Spring Boot.

Adrian Smith
  • 17,236
  • 11
  • 71
  • 93
  • 1
    Unfortunately the link "*Spring Boot's Flyway integration*" is broken. I think I'm facing [the same issue](https://stackoverflow.com/questions/50205340/flywaydb-migration-scripts-not-getting-executed) with flyway not getting run by spring. – Stefan Falk May 06 '18 at 23:29
  • Thanks for the headsup @StefanFalk. I've corrected it now. – Adrian Smith Aug 10 '18 at 10:58