Flyway failed to initialize: none of the following migration scripts locations could be found: - classpath:db / migrations - spring-boot

I have the below configurations in my application.properties and attached image is the classpath.
.
What I am missing?
spring.jpa.hibernate.ddl-auto = validate
spring.jpa.properties.hibernate.format_sql=true
#spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
# Flyway
spring.flyway.baselineOnMigrate=true
spring.flyway.check-location=true
spring.flyway.locations=classpath:db/migrations
spring.flyway.schemas=public
spring.flyway.enabled=true

The Flyway docs use a capital V for prefixing versioned migrations. Try to rename your migration from v1_1__init.sql to V1_1__init.sql.

Related

Flyway spring boot + java, new local database created by hibernate but now migrate tries to apply migrations that already happened

I initially created my project using hibernate to create tables like most people do, but then following recommendations I started using flyway to do db migrations.
Problem is I erased my entire local system including db and trying to spin it u again but I get conflicts of hibernate and flyway.
I'm using the java api by the way. So when I went to rebuild the database locally I turned on
spring.jpa.hibernate.ddl-auto=${HIBERNATE_DDL:create} just for the first run, then turned it to validate
So it built all the tables, but now when I try to launch the application it will try to run the first migration which is
ALTER TABLE public.auth ADD COLUMN resent boolean
which will cause an error on boot because that new column was added by hibernate
Error Code : 0
Message : ERROR: column "resent" of relation "auth" already exists
Location : db/migration/V1__Add_Resent_To_Auth.sql (/Users/brian/code/slap/build/resources/main/db/migration/V1__Add_Resent_To_Auth.sql)
Line : 1
Statement : ALTER TABLE public.auth
ADD COLUMN resent boolean
So how do I tell flyway that the current version is V9 and only run migrations after that. Shouldn't it just go look at the flyway_schema_history and see version 9 is the last entry then run migrations after that? I must be missing something
I tried doing this in my config to set the baseline version first
#Configuration
class FlyWay() {
#Value("\${spring.datasource.url}")
lateinit var url: String
#Value("\${spring.datasource.username}")
lateinit var username: String
#Value("\${spring.datasource.password}")
lateinit var password: String
#Bean
fun migrate() {
val flyway = Flyway.configure().baselineVersion("9.0").dataSource(url, username, password).load()
flyway.migrate()
}
}
no such luck it still tries to run V1
I tried adding it to application.properties too
spring.flyway.baselineVersion=9.0
same error
Scenario as I understood it:
Tables already exist
State of the tables corresponds to version "9.0"
Flyway baseline version should be set once for the local test DB
It might be useful to set the version via command line, since it is to be applied to the test database only once and then the normal migration strategies are to be applied.
Documentation see: https://flywaydb.org/documentation/usage/commandline/baseline
On macOS the Flyway command line client can be installed with brew install flyway.
Instructions
make sure the table flyway_schema_history is deleted. Use your preferred SQL client:
drop table flyway_schema_history;
then set the baseline version using the Flyway command line client (this example uses a Postgres database):
flyway -user=stephan -password= -url=jdbc:postgresql://localhost:5432/stephan -baselineVersion="9.0" -locations="src/main/resources/db/migration" baseline
check in SQL client:
select version from flyway_schema_history ;
This should show now "9.0". After that, the Spring Boot application should behave as usual.
Test
Alternative
For those people who prefer to do this with a Maven command:
drop the table flyway_schema_history like shown above
use the command mvn flyway:baseline -Dflyway.baselineVersion="9.0" to set the baseline version
This requires a bit of configuration in the pom.xml file, e.g. if using a Postgres database:
<build>
...
<plugins>
...
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>7.1.1</version>
<configuration>
<url>jdbc:postgresql://localhost:5432/stephan</url>
<user>stephan</user>
</configuration>
<dependencies>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.18</version>
</dependency>
</dependencies>
</plugin>
...
Test with Maven
A quick test shows the same result.
Why not export the SQL-script from your database (created by Hibernate) and add it as the first Flyway script into your application? It's the cleanest solution as Hibernate doesn't need to be started manually again when the application will run on other systems.
Just try once after adding the following line in your application.yml
spring.flyway.baseline-on-migrate: true

Unable to execute data.sql and schema.sql at Spring Boot Startup

I'm trying to execute some DB initialization for a Spring Boot application against a MySQL Database that is running in a container.
During the authentication process, I receive an error "Table not found". I've checked the DB and no tables have been created indeed.
Is there something missing in DB properties?
spring.datasource.url = jdbc:mysql://172.17.0.2:3306/schema
spring.datasource.username = user
spring.datasource.password = password
spring.datasource.testWhileIdle = true
spring.datasource.validationQuery = SELECT 1
spring.jpa.show-sql = true
spring.jpa.hibernate.ddl-auto = create-drop
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.data.rest.basePath=/
spring.datasource.data = classpath:/data.sql
spring.datasource.schema = classpath:/schema.sql
All in all, the JDBC Settings work fine provided that I create the DDL from the mysql command line. So it's just not executing the data.sql and schema.sql at startup.
Do I need some extra properties for mysql ?
You can update the application.properties with following properties.
application.properties:
spring.jpa.hibernate.ddl-auto=none
spring.jpa.generate-ddl=false
spring.datasource.initialization-mode=always
By default value of spring.jpa.generate-ddl is false. If you set spring.jpa.generate-ddl=true or spring.jpa.hibernate.ddl-auto to any of value validate, update, create, create-drop. Spring boot generates schema scripts and creates the tables based on the entities available in your application.
Now you should create the schema.sql and data.sql files under resources folder and set the property spring.datasource.initialization-mode=always in application.properties.
You can also run the scripts based on the platform. Let's suppose you want to run the scripts for hsqldb database, then set spring.datasource.platform=hsqldb in application.properties file and created scripts file schema-hsqldb.sql and data-hsqldb.sql under resources folder.
You can find more details about how to load schema.sql and data.sql on startup with spring boot.
Everything works as expected until a spring-boot update the pom file from
<version>1.5.8.RELEASE</version>
to
<version>2.3.3.RELEASE</version>
A switch back and update all test are passed without any exceptions. In Version 2.3.3 a test fault caused by missing data in database.
I've spend hours to solve the ddl initialization for Spring Version 2.3.3.RELEASE without find regular solution.
As you have
spring.jpa.hibernate.ddl-auto = create-drop
Spring doesn't run the schema.sql and data.sql.
Try it with
spring.jpa.hibernate.ddl-auto = none
Check the docs
In a JPA-based app, you can choose to let Hibernate create the schema or use schema.sql, but you cannot do both. Make sure to disable spring.jpa.hibernate.ddl-auto if you use schema.sql.
For spring boot version 2.7, ensure that you have configured spring.sql.init.mode property in the application.properties file
Example:
spring.sql.init.mode=always
spring.jpa.hibernate.ddl-auto=update
spring.jpa.generate-ddl=true

Flyway: Found non-empty schema(s) "public" without schema history table! Use baseline() - on Empty database

I am trying to configure flyway with kotlin Spring boot, jpa and postgreSQL. My gradle dependencies are:
dependencies {
implementation('org.springframework.boot:spring-boot-starter-data-jpa')
implementation('org.springframework.boot:spring-boot-starter-web')
implementation('com.fasterxml.jackson.module:jackson-module-kotlin')
implementation('org.flywaydb:flyway-core')
implementation('com.google.code.gson:gson')
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("org.jetbrains.kotlin:kotlin-reflect")
runtimeOnly('org.postgresql:postgresql')
testImplementation('org.springframework.boot:spring-boot-starter-test')
}
My application.properties file is:
spring.datasource.driverClassName=org.postgresql.Driver
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.datasource.url=jdbc:postgresql://${JDBC_DATABASE_URL}/jpaTestDatabase
spring.datasource.username=${JDBC_DATABASE_USERNAME}
spring.datasource.password=${JDBC_DATABASE_PASSWORD}
flyway.baseline-on-migrate=true
flyway.locations=classpath:src/main/kotlin/db/migration
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=validate
spring.session.store-type=none
Creating tables and entries using jpa and hibernate works as expected.
However a sample migration on an empty database results in:
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]:
Invocation of init method failed; nested exception is org.flywaydb.core.api.FlywayException:
Found non-empty schema(s) "public" without schema history table! Use baseline() or set baselineOnMigrate to true to initialize the schema history table.
my directory structure is the default one generated by spring initializr and my migrations are in: demo/src/main/kotlin/db/migration
I only have a single migration which is the kotlinized version of the example migration found here which I adapted to look line this:
class V1__Sample : BaseJavaMigration() {
override fun migrate(context: Context?) {
val statement = context?.connection?.prepareStatement(
"""
CREATE TABLE article (
id bigserial primary key,
name varchar(20) NOT NULL,
desc text NOT NULL
);
"""
)
statement.use { it?.execute() }
}
}
What am I missing here? Why does Flyway keep complaining about finding non-empty schema(s) "public" without schema history table, when the database is completelly empty (clean docker image)?
Assuming that you are using spring-boot version 2.
In spring boot 2 the prefix is "spring.flyway" so try adding prefix spring like below.
spring.flyway.baseline-on-migrate = true
OR
spring.flyway.baselineOnMigrate = true
may be you can try mvn flyway:clean && mvn flyway:migrate
Please check the search path of your database, if the public schema (on which flyway is creating its log tables) is not in the first place, it may not be able to find the log table and may complain that schema history is not found...
Please note that, if you are baselining, you need to remove old scripts from the scripts folder, else it will re-attempt it.

Liquibase Gradle plugin appears to have url and referenceUrl reversed

I have a very simple Spring Boot 2.0.4 project. Following the various examples for setting up the Liquibase Gradle plugin I wanted to be able to run the diffChangeLog target to update my change log XML file. The configuration looks like this:
liquibase {
activities {
main {
url 'jdbc:postgresql://localhost:5432/example_db'
username 'user'
password 'password'
driver 'org.postgresql.Driver'
referenceUrl 'hibernate:spring:com.example?dialect=org.hibernate.dialect.PostgreSQL9Dialect&hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy&hibernate.implicit_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy'
referenceDriver 'liquibase.ext.hibernate.database.connection.HibernateDriver'
classpath 'src/main'
changeLogFile "src/main/resources/db/changelog/master.xml"
}
runList = 'main'
}
}
The database is empty except for the databasechangelog and databasechangeloglock tables. When I run gradle diffChangeLog the change log XML file is never updated. The output from gradle diff shows "NONE" for everything. My project does have an entity and it is annotated with #Entity.
What am I doing wrong?

Spring flyway configuration: cannot find placeholders when running sql

I am trying to run gradlew flywayMigrate, and the application chrashes when running a recurring migration with the error
Caused by: org.flywaydb.core.api.FlywayException: No value provided for placeholder expressions: ${dbLinkHost}, ${dbLinkPassword}, ${dbLinkSid}, ${dbLinkUser}. Check your configuration!
The variables are configured like this in application.yml:
flyway:
placeholders:
dbLinkHost: ...
dbLinkSid: ...
dbLinkUser: ...
dbLinkPassword: ...
And I try to access them like this in the sql file:
'${dbLinkHost}'
Does anyone know why the declarations in application.yml don`t seem to be accessible here?
As a result of Spring Boot Issue #9896 - Move Flyway configuration properties to spring.flyway and commit f9e3163, starting with v2.0.0.M4, Flyway configuration properties in your application properties start with spring.flyway. To configure Flyway placeholders, for example:
spring:
flyway:
placeholders:
dbLinkHost: ...
dbLinkSid: ...
dbLinkUser: ...
dbLinkPassword: ...
In Spring Boot versions before v2.0.0.M4 such as the recently-released v1.5.14.RELEASE, Flyway configuration properties start with flyway.

Resources