<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Flyway Archives - Codersee blog- Kotlin on the backend</title>
	<atom:link href="https://blog.codersee.com/tag/flyway/feed/" rel="self" type="application/rss+xml" />
	<link></link>
	<description>Kotlin &#38; Backend Tutorials - Learn Through Practice.</description>
	<lastBuildDate>Wed, 16 Apr 2025 04:50:21 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://blog.codersee.com/wp-content/uploads/2025/04/cropped-codersee_logo_circle_2-32x32.png</url>
	<title>Flyway Archives - Codersee blog- Kotlin on the backend</title>
	<link></link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Add Flyway To An Existing Spring Boot Project</title>
		<link>https://blog.codersee.com/add-flyway-to-existing-spring-boot-project/</link>
					<comments>https://blog.codersee.com/add-flyway-to-existing-spring-boot-project/#respond</comments>
		
		<dc:creator><![CDATA[Piotr]]></dc:creator>
		<pubDate>Thu, 08 Dec 2022 18:16:48 +0000</pubDate>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[Flyway]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[Spring Boot]]></category>
		<guid isPermaLink="false">https://codersee.com/?p=5504025</guid>

					<description><![CDATA[<p>In this, the third article about Flyway on my blog, we will see how to add Flyway to an existing Spring Boot project. </p>
<p>The post <a href="https://blog.codersee.com/add-flyway-to-existing-spring-boot-project/">Add Flyway To An Existing Spring Boot Project</a> appeared first on <a href="https://blog.codersee.com">Codersee blog- Kotlin on the backend</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2 class="article-heading-introduction">1. Introduction</h2>
<p>In this article, which is a continuation of a <a href="https://flywaydb.org/" target="_blank" rel="noopener">Flyway</a> series we will learn how to <strong>add Flyway to an existing Spring Boot Project</strong>.</p>
<p>If you are not sure what this tool can bring to your project, then check out my first post on <a href="https://blog.codersee.com/flyway-migrations-with-spring-boot/">Flyway with Spring Boot</a>, where you can find all the necessary information.</p>
<h2 class="article-heading-introduction">2. Project Setup</h2>
<p>This time, we won&#8217;t spend time preparing a sample project (well, if you are here then there&#8217;s a 95% chance that you already have some project).</p>
<p>Nevertheless, if you don&#8217;t have one, but still would like to learn how to add a flyway to an existing Spring Boot project, then no worries. You can find an example project in<a href="https://github.com/codersee-blog/spring-boot-add-flyway-to-existing-project" target="_blank" rel="noopener"> this GitHub repository</a>.</p>
<blockquote><p><strong>Note: </strong>If you use the project from the linked repository, then please run the script.sql file (can be found in /resources/sql directory) against your database, before you start the application.</p></blockquote>
<h2 class="article-heading-introduction">3. Strategy For Adding Flyway To Existing Spring Boot Project</h2>
<p>Before we start anything, I just wanted to emphasize that <strong>we should always create a backup, before performing any operations on our databases</strong>. Regardless of how widely used, or well-tested the tool is, something can always go wrong and we have to be ready to roll out plan B.</p>
<h3 class="article-heading-introduction">3.1 Add Flyway Dependency</h3>
<p>As the first thing (after the backup!), let&#8217;s add the necessary dependency to our Spring Boot project.</p>
<p>For gradle, it will look as follows:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="groovy">implementation 'org.flywaydb:flyway-core:9.8.3'</pre>
<p>On the other hand, when working with Maven, we need to add these lines:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="xml">&lt;dependency&gt;
  &lt;groupId&gt;org.flywaydb&lt;/groupId&gt;
  &lt;artifactId&gt;flyway-core&lt;/artifactId&gt;
  &lt;version&gt;9.8.3&lt;/version&gt;
&lt;/dependency&gt;</pre>
<h3 class="article-heading-introduction">3.2 Verify Spring Boot App</h3>
<p>Nextly, let&#8217;s run our Spring Boot application and verify, whether anything changed:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="raw">org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flywayInitializer' defined in class path resource [org/springframework/boot/autoconfigure/flyway/FlywayAutoConfiguration$FlywayConfiguration.class]: Found non-empty schema(s) "custom_schema" but no schema history table. Use baseline() or set baselineOnMigrate to true to initialize the schema history table.
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1751) ~[spring-beans-6.0.2.jar:6.0.2]</pre>
<p>As we can clearly see, Flyway throws a pretty descriptive message:</p>
<blockquote><p>Found non-empty schema(s) &#8220;custom_schema&#8221; but no schema history table. Use baseline() or set baselineOnMigrate to true to initialize the schema history table.</p></blockquote>
<p>And basically, this error clearly states what we need to do when adding a Flyway to an existing project. But before that, we have to take care of a couple of things.</p>
<h3 class="article-heading-introduction">3.3 Generate Production Database DDL</h3>
<p>Firstly, we have to generate an <strong>SQL script containing the DDL our production database</strong>, including:</p>
<ul>
<li>procedures</li>
<li>views,</li>
<li>triggers etc&#8230;</li>
</ul>
<p>I won&#8217;t go into details here, because DDL script generation depends on the database you are using. Nevertheless, it can be done pretty easily with tools like <em>DataGrip</em>, <em>DBeaver</em>, or <em>pg_dump</em>.<br />
<a href="https://codersee.com/newsletter/"><img fetchpriority="high" decoding="async" class="aligncenter wp-image-3002956 size-large" src="http://blog.codersee.com/wp-content/uploads/2022/05/join_newsletter-1024x576.png" alt="Image shows two ebooks people can get for free after joining newsletter" width="800" height="419" /></a></p>
<p>And when the SQL script with DDL is ready, let&#8217;s save it in the Flyway migrations directory (in Spring Boot the default one is <em>resources/db/migration)</em>. Of course, we have to remember about the Flyway files naming convention, so the file name should be something, like <em>V1__my_custom_init_script.sql</em>.</p>
<h3 class="article-heading-introduction">3.4 Clear Irrelevant Data</h3>
<p>If you have only one database instance in your project, then feel free to skip this point. Otherwise,<strong> we have to make sure that the generated DDL script will work in every other environment</strong>. And we can achieve it in two ways:</p>
<ul>
<li><strong>if we don&#8217;t care about the data</strong> in other environments- then we can run the Flyway <em>clean</em> command.</li>
<li>however, <strong>if we do actually care about the data</strong> in our non-production environments, then there&#8217;s no other choice than to manually verify and align other database structures with the main one.</li>
</ul>
<p>The choice here is yours and will depend on many factors, like the importance of test data, amount of environments, etc.</p>
<p>Nevertheless, if you would like to clean your database before adding a Flyway to your existing project, then you can do that with the following:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="raw">flyway -defaultSchema="custom_schema" \
  -url="jdbc:postgresql://{URL}:{PORT}/{DB_NAME}" \
  -cleanDisabled="false" \
  -user="{USERNAME}" \
  clean</pre>
<p>Please keep in mind that with this command, we will be prompted to enter the password manually (and alternatively, we can pass the <em>-password</em> flag).</p>
<h3 class="article-heading-introduction">3.5 Add Flyway To Existing Spring Boot Project</h3>
<p>Finally, with all that being done, we can return to the Spring Boot project and make the necessary changes.</p>
<p>Let&#8217;s navigate to the <strong>application.yaml</strong> file and insert these settings:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="yaml">spring:
  flyway:
    baselineOnMigrate: true
    defaultSchema: "custom_schema" # not necessary, but most likely you'll want to point to a specific schema</pre>
<p>As we can see, with <strong>baselineOnMigrate</strong> set to true, we instruct Flyway to <strong>automatically call baseline when migration is executed against a non-empty schema</strong>. Additionally, we set the <strong>defaultSchema</strong> value, but this is totally optional.</p>
<p>As a result, the <strong>flyway_schema_history</strong> table is added to our schema:</p>
<p><img decoding="async" class="aligncenter wp-image-5504072 size-full" src="http://blog.codersee.com/wp-content/uploads/2022/12/flyway_schema_history_table_structure.png" alt="Image presents screenshot with flyway_schema_history table structure, which was added when we add Flyway to existing Spring Boot project." width="837" height="218" srcset="https://blog.codersee.com/wp-content/uploads/2022/12/flyway_schema_history_table_structure.png 837w, https://blog.codersee.com/wp-content/uploads/2022/12/flyway_schema_history_table_structure-300x78.png 300w, https://blog.codersee.com/wp-content/uploads/2022/12/flyway_schema_history_table_structure-768x200.png 768w" sizes="(max-width: 837px) 100vw, 837px" /></p>
<p>and populated with <strong>precisely one record</strong>.</p>
<p>Please remember that the <strong>baselineOnMigrate set to true is only required once- when we do the initial deployment</strong> and can be removed after that.</p>
<h3 class="article-heading-introduction">3.6 Add Flyway Using Commands</h3>
<p>Basically, with all of the above being done we are finished and can enjoy the benefits of Flyway in our project.</p>
<p>However, if you would like to learn how to add Flyway to an existing project using CLI, then you can do exactly the same with the following command:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="raw">flyway -defaultSchema="custom_schema" \ 
-url="jdbc:postgresql://{HOST}:{PORT}/{DB_NAME}" \
-user="USERNAME" \
-baselineOnMigrate="true" \
-locations="filesystem:." migrate</pre>
<p>Or, alternatively<strong>, run baseline only: </strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="raw">flyway -defaultSchema="custom_schema" \ 
-url="jdbc:postgresql://{HOST}:{PORT}/{DB_NAME}" \
-user="USERNAME" \
-locations="filesystem:." baseline</pre>
<p>And then <strong>the migrate command</strong>:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="raw">flyway -defaultSchema="custom_schema" \ 
-url="jdbc:postgresql://{HOST}:{PORT}/{DB_NAME}" \
-user="USERNAME" \
-locations="filesystem:." migrate</pre>
<p>These commands might be useful if you would like to extract migrations to a separate directory (and/or repository).</p>
<h2>4. Add Flyway To An Existing Spring Boot Project Summary</h2>
<p>And that would be all in this article about how to add Flyway to an existing Spring Boot project. If you&#8217;d like to get to know Flyway better, then I highly encourage you to visit <a href="https://flywaydb.org/documentation/" target="_blank" rel="noopener">their documentation</a>.</p>
<p>Let me know in the comments section in case of any questions 🙂</p>
<p>The post <a href="https://blog.codersee.com/add-flyway-to-existing-spring-boot-project/">Add Flyway To An Existing Spring Boot Project</a> appeared first on <a href="https://blog.codersee.com">Codersee blog- Kotlin on the backend</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.codersee.com/add-flyway-to-existing-spring-boot-project/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Flyway Migrations With Spring WebFlux (R2DBC)</title>
		<link>https://blog.codersee.com/flyway-spring-webflux/</link>
					<comments>https://blog.codersee.com/flyway-spring-webflux/#comments</comments>
		
		<dc:creator><![CDATA[Piotr]]></dc:creator>
		<pubDate>Tue, 31 May 2022 05:41:27 +0000</pubDate>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[Flyway]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[Spring Boot]]></category>
		<category><![CDATA[Spring WebFlux]]></category>
		<guid isPermaLink="false">https://codersee.com/?p=2502876</guid>

					<description><![CDATA[<p>In this article I will show you how to configure Flyway migrations when working with Spring WebFlux and Spring Data R2DBC.</p>
<p>The post <a href="https://blog.codersee.com/flyway-spring-webflux/">Flyway Migrations With Spring WebFlux (R2DBC)</a> appeared first on <a href="https://blog.codersee.com">Codersee blog- Kotlin on the backend</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2 class="article-heading-introduction">1. Introduction</h2>
<p>In this short article, I would like to show you how to configure <strong>Flyway</strong> when working with<strong> Spring WebFlux and Spring Data R2DBC</strong>.</p>
<p>In my <a href="https://blog.codersee.com/flyway-migrations-with-spring-boot/" target="_blank" rel="noopener">previous tutorial</a>, we&#8217;ve learned a lot about Flyway itself and how to set it up correctly, when working with Spring Boot. Nevertheless, if we would like to apply this knowledge when building a reactive web application with Spring WebFlux and Spring Data R2DBC, we would have to take a different approach. And that&#8217;s what we are going to focus on in this tutorial.</p>
<h2 class="article-heading-introduction">2. Imports</h2>
<h3 class="article-heading-introduction">2.1. Create Spring WebFlux With R2DBC Project</h3>
<p>As the first step, let&#8217;s create a skeleton project. We can do so by simply going to the <a href="https://start.spring.io/" target="_blank" rel="noopener">Spring Initializr</a> page and selecting the following dependencies:</p>
<ul>
<li>Spring Reactive Web</li>
<li>Spring Data R2DBC</li>
<li>PostgreSQL Driver</li>
</ul>
<p>After that, we should see the following in our <code class="EnlighterJSRAW" data-enlighter-language="kotlin">build.gradle.kts</code> file:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="kotlin">implementation("org.springframework.boot:spring-boot-starter-data-r2dbc")
implementation("org.springframework.boot:spring-boot-starter-webflux")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
runtimeOnly("org.postgresql:postgresql")
runtimeOnly("org.postgresql:r2dbc-postgresql")

// other dependencies</pre>
<h3 class="article-heading-introduction">2.2. Add Flyway Dependency</h3>
<p>Unfortunately, we can&#8217;t add the Flyway dependency to our Spring WebFlux project on the same page, so we have to do it manually:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="kotlin">implementation("org.flywaydb:flyway-core:8.5.11")</pre>
<p>With that being done, we have to reload Gradle changes and wait till the additional dependency is fetched to our environment.</p>
<p>&nbsp;</p>
<p><a href="https://codersee.com/newsletter/"><img decoding="async" class="aligncenter wp-image-3002956 size-large" src="http://blog.codersee.com/wp-content/uploads/2022/05/join_newsletter-1024x576.png" alt="Image shows two ebooks people can get for free after joining newsletter" width="800" height="419" /></a></p>
<p>&nbsp;</p>
<h2 class="article-heading-introduction">3. Configure application.properties (or YAML) File</h2>
<p>As the next step, let&#8217;s head to the <code class="EnlighterJSRAW" data-enlighter-language="kotlin">application.properties</code> file (or <code class="EnlighterJSRAW" data-enlighter-language="kotlin">application.yaml</code> in my case) and configure database connection along with Flyway:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="yaml">spring:
  r2dbc:
    url: r2dbc:postgresql://localhost:5432/
    username: postgres
    password: password
  flyway:
    url: jdbc:postgresql://localhost:5432/
    user: postgres
    password: password</pre>
<p>Please keep in mind that the values used for port, username, and password may be different in your case. Moreover, in the case of the Flyway connection, we have to use <strong>JDBC</strong>.</p>
<h2 class="article-heading-introduction">4. Implement Flyway Migration</h2>
<p>Nextly, let&#8217;s prepare an SQL file, which we would like to run as the first migration. Let&#8217;s call it <strong>V1__My_First_Migration.sql</strong>:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="sql">CREATE TABLE person(
  id SERIAL NOT NULL PRIMARY KEY,
  email TEXT NOT NULL
);</pre>
<p>As we can see, this simple script will create a new table called <code class="EnlighterJSRAW" data-enlighter-language="raw">person</code>. Please remember to put this file in the correct directory-<strong> resources/db/migration/</strong> in our case.</p>
<h2 class="article-heading-introduction">5. Add Flyway Configuration For R2DBC</h2>
<p>As the next step, let&#8217;s run our application to see if our Flyway migration is working. Technically, the app started successfully. Nevertheless, logs do not contain anything about applied migration and when we check the database we can clearly see, that <strong>migration was not run</strong>.</p>
<p>To change that, let&#8217;s add a <code class="EnlighterJSRAW" data-enlighter-language="kotlin">FlywayConfiguration</code> file to our project:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="kotlin">@Configuration
class FlywayConfiguration(private val env: Environment) {

    @Bean(initMethod = "migrate")
    fun flyway(): Flyway {
        return Flyway(Flyway.configure()
            .dataSource(
                env.getRequiredProperty("spring.flyway.url"),
                env.getRequiredProperty("spring.flyway.user"),
                env.getRequiredProperty("spring.flyway.password"))
        )
    }
}</pre>
<p>Alternatively, we can use <code class="EnlighterJSRAW" data-enlighter-language="kotlin">@Value</code> annotation, as well:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="kotlin">@Configuration
class FlywayConfiguration(
    @Value("\${spring.flyway.url}") private val url: String,
    @Value("\${spring.flyway.user}") private val user: String,
    @Value("\${spring.flyway.password}") private val password: String
) {

    @Bean(initMethod = "migrate")
    fun flyway(): Flyway {
        return Flyway(
            Flyway.configure()
                .dataSource(url, user, password)
        )
    }
}</pre>
<p>As we can see, this configuration is responsible for creating a new Flyway bean with the URL, username, and password obtained from our <code class="EnlighterJSRAW" data-enlighter-language="kotlin">application.yaml</code> file.</p>
<p>If we rerun our app once again, we will see the following:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">Creating Schema History table "public"."flyway_schema_history" ...
Current version of schema "public": &lt;&lt; Empty Schema &gt;&gt;
Migrating schema "public" to version "1 - My First Migration"
Successfully applied 1 migration to schema "public", now at version v1 (execution time 00:00.034s)</pre>
<p>The above message clearly indicates that the migration was run and we can expect a new table in our database.</p>
<h2 class="article-heading-introduction">6. Summary</h2>
<p>And that would be all for this short article on how to configure <strong>Flyway migrations with Spring WebFlux and R2DBC</strong>.</p>
<p>Let me know if you found this material useful in the comment sections below, or by using the <a href="https://codersee.com/contact/" target="_blank" rel="noopener">contact form</a>.</p>
<p>Finally, if you would like to see the whole source code, please refer to this <a href="https://github.com/codersee-blog/spring-webflux-flyway" target="_blank" rel="noopener">GitHub repository</a>.</p>
<p>The post <a href="https://blog.codersee.com/flyway-spring-webflux/">Flyway Migrations With Spring WebFlux (R2DBC)</a> appeared first on <a href="https://blog.codersee.com">Codersee blog- Kotlin on the backend</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.codersee.com/flyway-spring-webflux/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Flyway Migrations With Spring Boot</title>
		<link>https://blog.codersee.com/flyway-migrations-with-spring-boot/</link>
					<comments>https://blog.codersee.com/flyway-migrations-with-spring-boot/#respond</comments>
		
		<dc:creator><![CDATA[Piotr]]></dc:creator>
		<pubDate>Mon, 23 May 2022 06:00:21 +0000</pubDate>
				<category><![CDATA[Databases]]></category>
		<category><![CDATA[Spring]]></category>
		<category><![CDATA[Flyway]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[Spring Boot]]></category>
		<guid isPermaLink="false">https://codersee.com/?p=2502844</guid>

					<description><![CDATA[<p>In this tutorial, we will learn what exactly Flyway is and how we can configure it when working with Spring Boot.</p>
<p>The post <a href="https://blog.codersee.com/flyway-migrations-with-spring-boot/">Flyway Migrations With Spring Boot</a> appeared first on <a href="https://blog.codersee.com">Codersee blog- Kotlin on the backend</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading" id="h-1-introduction">1. Introduction</h2>



<p>In this blog post, I would like to show you what exactly <a href="https://flywaydb.org/" target="_blank" rel="noopener">Flyway</a> is and how to configure it, when working with<strong> Spring Boot.</strong></p>



<p>Together, we will spend some time to figure out:</p>



<ul class="wp-block-list">
<li>why do we even need it in our project?</li>



<li>how can we quickly configure Flyway with Spring Boot?</li>



<li>finally, how can we customize its behavior?</li>
</ul>



<h2 class="wp-block-heading" id="h-2-what-is-flyway-and-what-problems-does-it-solve">2. What is Flyway and What Problems Does It Solve?</h2>



<p>To put it simply, Flyway is a <strong>database versioning tool</strong>. Just like Git is a version control system for our codebase, Flyway takes care of<strong> database schema management</strong>.</p>



<p>Let&#8217;s imagine that we&#8217;ve started a Spring Boot project, which communicates with the PostgreSQL database. We&#8217;ve been working on our own, implementing new features, adding new tables, and changing the schema many times. At some point, a new programmer joins our team, so we simply export our local or remote database and send him the script, so that he will be able to set up a local environment.</p>



<p>So far so good, but what will happen when more people join our team? Or we would like to create more testing environments? Of course, we could save the script and update it each time, we change anything, but this can introduce plenty of problems, for example:</p>



<ul class="wp-block-list">
<li>when multiple people are editing schema asynchronously, how can we make sure that all their scripts are applied in a specific environment?</li>



<li>how can we be sure that all developers have exactly the same (or a specific) version on their local?</li>



<li>how can we determine the correct order of scripts, so that nothing breaks when applying them?</li>
</ul>



<p>If you are not convinced after reading the above points, then imagine working without Git when cooperating with others and exchanging written code manually 🙂 Technically- doable- nevertheless definitely not recommended.</p>



<p>Of course, Flyway is not the only tool we could use with Spring Boot, however, it is definitely<strong> easy to work with</strong>.</p>


<p>[elementor-template id=&#8221;9007393&#8243;]</p>



<h2 class="wp-block-heading" id="h-3-setup-flyway-with-spring-boot">3. Setup Flyway With Spring Boot</h2>



<p>With all of that being said, let&#8217;s switch to the practice part. If you would like to simply download the skeleton for this tutorial, I&#8217;ve uploaded it to <a href="https://github.com/codersee-blog/spring-boot-flyway-skeleton" target="_blank" rel="noopener">this GitHub repository</a>. Nevertheless, I highly encourage you to set up the Spring Boot project on your own and follow below steps. This way, you&#8217;re definitely gonna learn more.</p>



<h3 class="wp-block-heading" id="h-3-1-imports">3.1. Imports</h3>



<p>As the first step, let&#8217;s add the necessary imports:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">implementation("org.flywaydb:flyway-core:10.13.0")
runtimeOnly("org.flywaydb:flyway-database-postgresql:10.13.0")
implementation("org.postgresql:postgresql:42.7.3")
implementation("org.springframework.boot:spring-boot-starter-data-jdbc") //alternatively, we could use spring-boot-starter-data-jpa</pre>



<p>The above 4 are the bare minimum required to work with Flyway and Spring Boot.</p>



<h3 class="wp-block-heading" id="h-3-2-edit-application-properties">3.2. Edit Application Properties</h3>



<p>As the next step, we have to make sure that we&#8217;ve set up the database connection properly.</p>



<p>The easiest way to do so is via <strong>application.yaml</strong> (or <strong>application.properties</strong>) file:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">spring:
  datasource:
    url: "jdbc:postgresql://localhost:5432/your-db-name"
    username: db-username
    password: db-password</pre>



<p>By default, Flyway will use the <strong>@Primary Data Source</strong> (which we&#8217;ve configured above).</p>



<h3 class="wp-block-heading" id="h-3-3-add-migrations-directory">3.3. Add Migrations Directory</h3>



<p>Nextly, we have to add <strong>/db/migration</strong> directory to the <strong>/resources</strong>. If we don&#8217;t do so and try to run the application, it will fail with the following error:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Flyway failed to initialize: none of the following migration scripts locations could be found:</p>
</blockquote>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>classpath:db/migration</p>
</blockquote>



<p>Of course, we can customize that, and we will learn how to do that later.</p>



<h3 class="wp-block-heading" id="h-3-4-validation">3.4. Validation</h3>



<p>For now, let&#8217;s check if our setup is working correctly (please make sure that you have a database with an empty schema <strong>up and running</strong>).</p>



<p>After we run the application, we should see the following in the logs:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Flyway Community Edition 8.5.11 by Redgate
...
Successfully validated 0 migrations (execution time 00:00.009s)
No migrations found. Are your locations set up correctly?
Creating Schema History table "public"."flyway_schema_history" ...
Schema "public" is up to date. No migration necessary.
</pre>



<p>Moreover, we can see that a new table called <strong>flyway_schema_history</strong> was added to our schema.</p>



<p>In brief, Flyway uses this table to manage versions and control applied, modified or added scripts. If you would like to see more theory, then <a href="https://flywaydb.org/documentation/getstarted/how" target="_blank" rel="noopener">this article</a> from their documentation is a great source for that.</p>



<h3 class="wp-block-heading" id="h-3-5-add-a-migration">3.5. Add a Migration</h3>



<p>Finally, let&#8217;s add our first migration file called <strong>V1__Create_User_Table.sql</strong>. This &#8220;strange&#8221; filename is the<strong> default Flyway naming convention</strong>, which consists of:</p>



<ul class="wp-block-list">
<li><strong>a prefix</strong>&#8211; <strong>B</strong> for baseline, <strong>R</strong> for repeatable,  <strong>U</strong> for undo, and <strong>V</strong> for versioned migrations</li>



<li><strong>migration number</strong>&#8211; number <strong>1</strong> in our case. If we would like it to be <strong>1.1</strong>, then we should start the name with <strong>V1_1</strong></li>



<li><strong>double underscore</strong>&#8211; separates version from migration description</li>



<li><strong>description</strong>&#8211; underscores are translated to spaces, so our migration will become <strong>Create User Table </strong></li>
</ul>



<p>With that being said, let&#8217;s add an example SQL script:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="sql" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">CREATE TABLE IF NOT EXISTS app_user (
  id SERIAL NOT NULL PRIMARY KEY,
  name TEXT NOT NULL
);
</pre>



<p>After that, let&#8217;s run our Spring Boot application once again and check out printed logs:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">Migrating schema "public" to version "1 - Create User Table"</pre>



<p>As can be seen, migration was applied successfully and a new table was added to our database.</p>



<h2 class="wp-block-heading" id="h-4-flyway-customization-with-application-properties">4. Flyway Customization With application.properties</h2>



<h3 class="wp-block-heading" id="h-4-1-enable-disable-flyway">4.1. Enable/Disable Flyway</h3>



<p>By default, Flyway is enabled when added to Spring Boot. Nevertheless, if we would like to change that, we can set the <strong>enabled</strong> flag:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">spring:
  flyway:
    enabled: false</pre>



<h3 class="wp-block-heading" id="h-4-2-set-custom-migrations-directory">4.2. Set Custom Migrations Directory</h3>



<p>As I&#8217;ve mentioned earlier, the default directory is <strong>/db/migration</strong>, but it can be customized with <strong>spring.flyway.locations</strong> property:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">spring:
  flyway:
    locations: "classpath:my-custom-dir,classpath:my-custom-dir-2"</pre>



<p>As we can see, we can provide multiple directories. When working with Spring Boot, a <strong>classpath</strong> means <strong>resources</strong> directory. Alternatively, we can refer to any directory in the system using <strong>filesystem</strong> instead.</p>



<p>It&#8217;s worth mentioning that when we specify multiple directories, then at least one of them has to exist (but not all of them). Moreover, we can&#8217;t duplicate migration versions among our directories.</p>



<p>So, in practice:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="raw" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">/resources
    /my-custom-dir
        V2__one.sql
    /my-custom-dir-2
        V1__one.sql
</pre>



<p>These two directories are treated, just like one and if we would specify V1 version twice, then the <strong>FlywayException</strong> would be thrown:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Found more than one migration with version 1</p>
</blockquote>



<h3 class="wp-block-heading" id="h-4-3-vendor-aware-directory">4.3. Vendor Aware Directory</h3>



<p>Additionally, Flyway allows us not only to specify hard-coded paths, but we can use a <strong>vendor</strong> placeholder, which will be resolved on the fly:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">spring:
  flyway:
    locations: "classpath:my-custom-dir/{vendor}"</pre>



<p>With the above config, Flyway will look for migrations files inside the <strong>/resources/my-custom-dir/postgresql</strong> directory. You can find a full list of supported vendors <a href="https://github.com/spring-projects/spring-boot/blob/main/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/DatabaseDriver.java" target="_blank" rel="noopener">right here</a>.</p>



<h2 class="wp-block-heading" id="h-5-flyway-java-kotlin-configuration">5. Flyway Java (Kotlin) Configuration</h2>



<p>It&#8217;s worth mentioning that Flyway allows us to <strong>apply migrations written in Java</strong>. When working with Spring Boot, they will be auto-configured with any bean implementing a <strong>JavaMigration</strong> interface. However, this interface requires us to implement a few methods, so the recommended way is to extend the <strong>BaseJavaMigration</strong> abstract class instead (and sufficient in most cases).</p>



<p>Given that, let&#8217;s have a look at the example written in Kotlin (which technically does not differ too much from its Java counterpart):</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">@Component
class V1__Create_User_Table : BaseJavaMigration() {
    override fun migrate(context: Context) {
        val update = context.connection.createStatement()
        update.execute(
            """
            CREATE TABLE IF NOT EXISTS app_user (
                id SERIAL NOT NULL PRIMARY KEY, 
                name TEXT NOT NULL
            );
            """.trimIndent()
        )
    }
}

@Component
class V2__Drop_User_Table : BaseJavaMigration() {
    override fun migrate(context: Context) {
        val update = context.connection.createStatement()
        update.execute("DROP TABLE app_user;")
    }
}</pre>



<p>As we can see, the only thing we have to do is to override the <strong>migrate</strong> method, and that class names should follow the default Flyway naming convention.</p>



<p>If you are wondering whether we can <strong>mix SQL files with Spring Beans configuration</strong>, then the answer is <strong>yes</strong> (however we should be really cautious about it).</p>



<h2 class="wp-block-heading" id="h-6-flyway-with-spring-boot-summary">6. Flyway With Spring Boot Summary</h2>



<p>And that would be all for this tutorial about <strong>Flyway With Spring Boot</strong>. I believe the knowledge presented here will be sufficient to easily incorporate this tool into any <a href="https://blog.codersee.com/category/spring/" target="_blank" rel="noopener">Spring Boot</a> project. Moreover, if you&#8217;d like to learn how to incorporate Flyway to an existing Spring Boot project, or how to use it with Spring WebFlux, <strong>then check out the <a href="https://blog.codersee.com/tag/flyway/" target="_blank" rel="noopener">flyway tag</a></strong>.</p>



<p>Let me know what you think about database version control tools. Do you like Flyway, or maybe you prefer some other tool?</p>



<p>Have a great day and see you in the next articles! 🙂</p>
<p>The post <a href="https://blog.codersee.com/flyway-migrations-with-spring-boot/">Flyway Migrations With Spring Boot</a> appeared first on <a href="https://blog.codersee.com">Codersee blog- Kotlin on the backend</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.codersee.com/flyway-migrations-with-spring-boot/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Page Caching using Disk: Enhanced 

Served from: blog.codersee.com @ 2026-05-13 19:10:15 by W3 Total Cache
-->