= Flyway

:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR  CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

The _Flyway_ extension module provides a very thin layer to use Spring Boot's integration with https://flywaydb.org[Flyway]

== Setup

=== Dependency Management

Add a section for _Flyway_'s own BOM:

[source,xml,subs="attributes+"]
.pom.xml
----
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.apache.causeway.extensions</groupId>
            <artifactId>causeway-extensions-flyway</artifactId>
            <scope>import</scope>
            <type>pom</type>
            <version>{page-causewayprev}</version>
        </dependency>
    </dependencies>
</dependencyManagement>
----

[#dependencies]
=== Dependencies / Imports

In the webapp module of your application, add the following dependency:

[source,xml]
.pom.xml
----
<dependencies>
    <dependency>
        <groupId>org.apache.causeway.extensions</groupId>
        <artifactId>causeway-extensions-flyway-impl</artifactId>
    </dependency>
</dependencies>
----

In your application's xref:userguide::modules.adoc#appmanifest[App Manifest], import the _Flyway_ module.

[source,java]
----
@Configuration
@Import({
    ...
    CausewayModuleExtFlywayImpl.class,
    ...
})
public static class AppManifest {
}
----

[#configure-properties]
=== Configuration Properties

Configure Flyway connection parameters:

[source,properties]
.application.properties
----
spring.flyway.enabled=true
spring.flyway.default-schema=SIMPLE             // <.>
spring.flyway.schemas=SIMPLE                    // <.>
spring.flyway.create-schemas=true               // <.>

causeway.persistence.schema.auto-create-schemas=    // <.>
----
<.> the default schema managed by Flyway (containing the `schema_version` table); see link:https://flywaydb.org/documentation/configuration/parameters/defaultSchema[flyway.defaultSchema] config property (Flyway docs) for more info
<.> all of the schemas managed by Flyway; see link:https://flywaydb.org/documentation/configuration/parameters/schemas[flyway.schemas] config property (Flyway docs) for more info
<.> whether Flyway should automatically create schemas ; see link:https://flywaydb.org/documentation/configuration/parameters/createSchemas[flyway.createSchemas] for more info
<.> instruct Apache Causeway to _not_ attempt to create schemas

The ORM should also be configured to _not_ automatically create tables:

* if using xref:pjpa:ROOT:about.adoc[JPA/Eclipselink], then:
+
[source,properties]
.application.properties
----
eclipselink.ddl-generation=none
----

* if using xref:pjdo:ROOT:about.adoc[JDO/DataNucleus], then:
+
[source,properties]
.application.properties
----
datanucleus.schema.autoCreateAll=false
----


== Managing different variants

When running with an in-memory object store - either for prototyping or integration tests - you will need the database tables to be created first.

In normal circumstances this is most easily accomplished with the ORM automatically creating the tables (and Flyway disabled).

However, if you want your tests to check your Flyway scripts beforehand, there is nothing to prevent you from using Flyway all the time, even for integration tests.
One point to be aware of though is that the DDL syntax may vary between an in-memory database (such as H2) and a typical production database (such as PostgreSQL or SQL Server).

Luckily, Spring Boot's Flyway integration allows different variants of scripts for different vendors to be stored, in `+db.migration.{vendor}+` package (where `+{vendor}+` is as defined by the https://github.com/spring-projects/spring-boot/blob/v2.2.3.RELEASE/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DatabaseDriver.java[DatabaseDriver] class).
The xref:docs:starters:simpleapp.adoc[simpleapp starter app] also provides an example of this.



== See also

* https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto-execute-flyway-database-migrations-on-startup[Spring Boot docs] for Flyway integration
