Partner – Microsoft – NPI EA (cat = Baeldung)

Azure Container Apps is a fully managed serverless container service that enables you to build and deploy modern, cloud-native Java applications and microservices at scale. It offers a simplified developer experience while providing the flexibility and portability of containers.

Of course, Azure Container Apps has really solid support for our ecosystem, from a number of build options, managed Java components, native metrics, dynamic logger, and quite a bit more.

To learn more about Java features on Azure Container Apps, visit the documentation page.

You can also ask questions and leave feedback on the Azure Container Apps GitHub page.

Partner – Microsoft – NPI EA (cat= Spring Boot)

Azure Container Apps is a fully managed serverless container service that enables you to build and deploy modern, cloud-native Java applications and microservices at scale. It offers a simplified developer experience while providing the flexibility and portability of containers.

Of course, Azure Container Apps has really solid support for our ecosystem, from a number of build options, managed Java components, native metrics, dynamic logger, and quite a bit more.

To learn more about Java features on Azure Container Apps, you can get started over on the documentation page.

And, you can also ask questions and leave feedback on the Azure Container Apps GitHub page.

Partner – Orkes – NPI EA (cat=Spring)

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

Partner – Orkes – NPI EA (tag=Microservices)

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

eBook – Guide Spring Cloud – NPI EA (cat=Spring Cloud)

Let's get started with a Microservice Architecture with Spring Cloud:

>> Join Pro and download the eBook

eBook – Mockito – NPI EA (tag = Mockito)

Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.

Get started with mocking and improve your application tests using our Mockito guide:

Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Reactive – NPI EA (cat=Reactive)

Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:

>> Join Pro and download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Jackson – NPI EA (cat=Jackson)

Do JSON right with Jackson

Download the E-book

eBook – HTTP Client – NPI EA (cat=Http Client-Side)

Get the most out of the Apache HTTP Client

Download the E-book

eBook – Maven – NPI EA (cat = Maven)

Get Started with Apache Maven:

Download the E-book

eBook – Persistence – NPI EA (cat=Persistence)

Working on getting your persistence layer right with Spring?

Explore the eBook

eBook – RwS – NPI EA (cat=Spring MVC)

Building a REST API with Spring?

Download the E-book

Course – LS – NPI EA (cat=Jackson)

Get started with Spring and Spring Boot, through the Learn Spring course:

>> LEARN SPRING
Course – RWSB – NPI EA (cat=REST)

Explore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:

>> The New “REST With Spring Boot”

Course – LSS – NPI EA (cat=Spring Security)

Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.

I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.

You can explore the course here:

>> Learn Spring Security

Course – All Access – NPI EA (cat= Spring)

All Access is finally out, with all of my Spring courses. Learn JUnit is out as well, and Learn Maven is coming fast. And, of course, quite a bit more affordable. Finally.

>> GET THE COURSE
Course – LSD – NPI EA (tag=Spring Data JPA)

Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.

Get started with Spring Data JPA through the guided reference course:

>> CHECK OUT THE COURSE

Partner – LambdaTest – NPI EA (cat=Testing)

End-to-end testing is a very useful method to make sure that your application works as intended. This highlights issues in the overall functionality of the software, that the unit and integration test stages may miss.

Playwright is an easy-to-use, but powerful tool that automates end-to-end testing, and supports all modern browsers and platforms.

When coupled with LambdaTest (an AI-powered cloud-based test execution platform) it can be further scaled to run the Playwright scripts in parallel across 3000+ browser and device combinations:

>> Automated End-to-End Testing With Playwright

1. Introduction

In this tutorial, we’ll explore key concepts of Flyway and how we can use this framework to continuously remodel our application’s database schema reliably and easily. In addition, we’ll present an example of managing an in-memory H2 database using a Maven Flyway plugin.

Flyway updates a database from one version to the next using migrations. We can write migrations either in SQL with database-specific syntax, or in Java for advanced database transformations.

Further reading:

Use Liquibase to Safely Evolve a Database Schema

How to use Liquibase to safely and maturely evolve the database schema of your Java app.

Rolling Back Migrations with Flyway

Learn how to safely roll back migrations using Flyway.

A Guide to Flyway Callbacks

A guide to implementing SQL and Java command-callbacks in Flyway

Migrations can either be versioned or repeatable. The former has a unique version and is applied exactly once. The latter doesn’t have a version. Instead, they are (re-)applied every time their checksum changes.

Within a single migration run, repeatable migrations are always applied last, after pending versioned migrations have been executed. Repeatable migrations are applied in order of their description. For a single migration, all statements are run within a single database transaction.

In this tutorial, we’ll mainly focus on how we use the Maven plugin to perform database migrations.

2. Flyway Maven Plugin

To install a Flyway Maven plugin, let’s add the following plugin definition to our pom.xml:

<plugin>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-maven-plugin</artifactId>
    <version>10.17.0</version> 
</plugin>

The latest version of the plugin is available at Maven Central.

We can configure this Maven plugin in four different ways. In the following sections, we’ll go over each of these options.

Please refer to the documentation to get a list of all configurable properties.

2.1. Plugin Configuration

We can configure the plugin directly via the <configuration> tag in the plugin definition of our pom.xml:

<plugin>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-maven-plugin</artifactId>
    <version>10.17.0</version>
    <configuration>
        <user>databaseUser</user>
        <password>databasePassword</password>
        <schemas>
            <schema>schemaName</schema>
        </schemas>
        ...
    </configuration>
</plugin>

2.2. Maven Properties

We can also configure the plugin by specifying configurable properties as Maven properties in our pom:

<project>
    ...
    <properties>
        <flyway.user>databaseUser</flyway.user>
        <flyway.password>databasePassword</flyway.password>
        <flyway.schemas>schemaName</flyway.schemas>
        ...
    </properties>
    ...
</project>

2.3. External Configuration File

Another option is to provide plugin configuration in a separate .conf file:

flyway.user=databaseUser
flyway.password=databasePassword
flyway.schemas=schemaName
...

The default configuration file name is flyway.conf and by default it loads configuration files from:

  • installDir/conf/flyway.conf
  • userhome/flyway.conf
  • workingDir/flyway.conf

Encoding is specified by the flyway.encoding property (UTF-8 is the default one).

If we use any other name (e.g customConfig.conf) as the configuration file, then we have to specify this explicitly when invoking the Maven command:

$ mvn -Dflyway.configFiles=customConfig.conf

2.4. System Properties

Finally, all configuration properties can also be specified as system properties when invoking Maven on the command line:

$ mvn -Dflyway.user=databaseUser -Dflyway.password=databasePassword 
  -Dflyway.schemas=schemaName

The following is an order of precedence when a configuration is specified in more than one way:

  1. System properties
  2. External configuration file
  3. Maven properties
  4. Plugin configuration

3. Example Migration

In this section, we’ll walk through the required steps to migrate a database schema to an in-memory H2 database using the Maven plugin. We use an external file to configure Flyway.

3.1. Update POM

First, let’s add H2 as a dependency:

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
</dependency>

Again, we can check the latest version of the driver available on Maven Central. We also add the Flyway plugin as explained earlier.

3.2. Configure Flyway Using an External File

Next, we create myFlywayConfig.conf in $PROJECT_ROOT with the following content:

flyway.user=databaseUser
flyway.password=databasePassword
flyway.schemas=app-db
flyway.url=jdbc:h2:mem:DATABASE
flyway.locations=filesystem:db/migration

The above configuration specifies that our migration scripts are located in the db/migration directory. It connects to an in-memory H2 instance using databaseUser and databasePassword.

The application database schema is app-db.

Of course, we replace flyway.user, flyway.password, and flyway.url with our own database username, database password, and database URL, respectively.

3.3. Define First Migration

Flyway adheres to the following naming convention for migration scripts:

<Prefix><Version>__<Description>.sql

Where:

  • <Prefix> – The default prefix is V, which we can change in the above configuration file using the flyway.sqlMigrationPrefix property.
  • <Version> – Migration version number. Major and minor versions may be separated by an underscore. The migration version should always start with 1.
  • <Description> – Textual description of the migration. A double underscore separates the description from the version numbers.

Example: V1_1_0__my_first_migration.sql

So let’s create a directory db/migration in $PROJECT_ROOT with a migration script named V1_0__create_employee_schema.sql containing SQL instructions to create the employee table:

CREATE TABLE IF NOT EXISTS `employee` (

    `id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `name` varchar(20),
    `email` varchar(50),
    `date_of_birth` timestamp

)ENGINE=InnoDB DEFAULT CHARSET=UTF8;

3.4. Execute Migrations

Next, we invoke the following Maven command from $PROJECT_ROOT to execute database migrations:

$ mvn clean flyway:migrate -Dflyway.configFiles=myFlywayConfig.conf

This should result in our first successful migration.

The database schema should now look like this:

employee:
+----+------+-------+---------------+
| id | name | email | date_of_birth |
+----+------+-------+---------------+

We can repeat the definition and execution steps to do more migrations.

3.5. Define and Execute Second Migration

Let’s see what a second migration looks like by creating a second migration file with the name V2_0_create_department_schema.sql containing the following two queries:

CREATE TABLE IF NOT EXISTS `department` (

`id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` varchar(20)

)ENGINE=InnoDB DEFAULT CHARSET=UTF8; 

ALTER TABLE `employee` ADD `dept_id` int AFTER `email`;

Then we’ll execute a similar migration like we did the first time.

Now our database schema has changed to add a new column to employee and a new table:

employee:
+----+------+-------+---------+---------------+
| id | name | email | dept_id | date_of_birth |
+----+------+-------+---------+---------------+
department:
+----+------+
| id | name |
+----+------+

Finally, we can verify that both migrations were indeed successful by invoking the following Maven command:

$ mvn flyway:info -Dflyway.configFiles=myFlywayConfig.conf

4. Generate Versioned Migrations in IntelliJ IDEA

Writing migrations manually takes a lot of time; instead, we can generate them based on our JPA entities. We can achieve this by using a plugin for IntelliJ IDEA called JPA Buddy.

To generate a differential versioned migration, simply install the plugin and call the action from the JPA Structure panel.

We simply select which source we want to compare (database or JPA entities) with which target (database or data model snapshot). Then JPA Buddy will generate the migration as shown in the animation:

Another advantage of JPA Buddy is the ability to define mappings between Java and database types. Also, it works correctly with Hibernate custom types and JPA converters.

5. Disabling Flyway in Spring Boot

Sometimes we may need to disable Flyway migrations under certain circumstances.

For example, it’s common practice to generate database schema based on the entities during tests. In such a situation, we can disable Flyway under the test profile.

Let’s see how easy it is in Spring Boot.

5.1. Spring Boot 1.x

All we need to do is set the flyway.enabled property in our application-test.properties file:

flyway.enabled=false

5.2. Spring Boot 2.x, 3.x

In the more recent versions of Spring Boot, this property has been changed to spring.flyway.enabled:

spring.flyway.enabled=false

5.3. Empty FlywayMigrationStrategy

If we only want to disable automatic Flyway migration on startup, but still be able to trigger the migration manually, then using the properties described above isn’t a good choice.

That’s because in such a situation, Spring Boot will not auto-configure the Flyway bean anymore. Consequently, we’d have to provide it on our own, which isn’t very convenient.

So if this is our use case, we can leave Flyway enabled and implement an empty FlywayMigrationStrategy:

@Configuration
public class EmptyMigrationStrategyConfig {

    @Bean
    public FlywayMigrationStrategy flywayMigrationStrategy() {
        return flyway -> {
            // do nothing  
        };
    }
}

This will effectively disable Flyway migration on application startup.

However, we’ll still be able to trigger the migration manually:

@RunWith(SpringRunner.class)
@SpringBootTest
public class ManualFlywayMigrationIntegrationTest {

    @Autowired
    private Flyway flyway;

    @Test
    public void skipAutomaticAndTriggerManualFlywayMigration() {
        flyway.migrate();
    }
}

6. How Flyway Works

To keep track of which migrations we’ve already applied and when, it adds a special bookkeeping table to our schema. This metadata table also tracks migration checksums, and whether or not the migrations were successful.

The framework performs the following steps to accommodate evolving database schemas:

  1. It checks a database schema to locate its metadata table (SCHEMA_VERSION by default). If the metadata table doesn’t exist, it will create one.
  2. It scans an application classpath for available migrations.
  3. It compares migrations against the metadata table. If a version number is lower or equal to a version marked as current, it’s ignored.
  4. It marks any remaining migrations as pending migrations. These are sorted based on the version number and are executed in order.
  5. As each migration is applied, the metadata table is updated accordingly.

7. Commands

Flyway supports the following basic commands to manage database migrations:

  • Info: Prints current status/version of a database schema. It prints which migrations are pending, which migrations have been applied, the status of applied migrations, and when they were applied.
  • Migrate: Migrates a database schema to the current version. It scans the classpath for available migrations and applies pending migrations.
  • Baseline: Baselines an existing database, excluding all migrations, including baselineVersion. Baseline helps to start with Flyway in an existing database. Newer migrations can then be applied normally.
  • Validate: Validates current database schema against available migrations.
  • Repair: Repairs metadata table.
  • Clean: Drops all objects in a configured schema. Of course, we should never use clean on any production database.

8. Conclusion

In this article, we learned how Flyway works and how we can use this framework to remodel our application database reliably.

The code backing this article is available on GitHub. Once you're logged in as a Baeldung Pro Member, start learning and coding on the project.
Baeldung Pro – NPI EA (cat = Baeldung)

Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:

>> Explore a clean Baeldung

Once the early-adopter seats are all used, the price will go up and stay at $33/year.

Partner – Microsoft – NPI EA (cat = Spring Boot)

Azure Container Apps is a fully managed serverless container service that enables you to build and deploy modern, cloud-native Java applications and microservices at scale. It offers a simplified developer experience while providing the flexibility and portability of containers.

Of course, Azure Container Apps has really solid support for our ecosystem, from a number of build options, managed Java components, native metrics, dynamic logger, and quite a bit more.

To learn more about Java features on Azure Container Apps, visit the documentation page.

You can also ask questions and leave feedback on the Azure Container Apps GitHub page.

Partner – Orkes – NPI EA (cat = Spring)

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

Partner – Orkes – NPI EA (tag = Microservices)

Modern software architecture is often broken. Slow delivery leads to missed opportunities, innovation is stalled due to architectural complexities, and engineering resources are exceedingly expensive.

Orkes is the leading workflow orchestration platform built to enable teams to transform the way they develop, connect, and deploy applications, microservices, AI agents, and more.

With Orkes Conductor managed through Orkes Cloud, developers can focus on building mission critical applications without worrying about infrastructure maintenance to meet goals and, simply put, taking new products live faster and reducing total cost of ownership.

Try a 14-Day Free Trial of Orkes Conductor today.

eBook – HTTP Client – NPI EA (cat=HTTP Client-Side)

The Apache HTTP Client is a very robust library, suitable for both simple and advanced use cases when testing HTTP endpoints. Check out our guide covering basic request and response handling, as well as security, cookies, timeouts, and more:

>> Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Persistence – NPI EA (cat=Persistence)

Working on getting your persistence layer right with Spring?

Explore the eBook

Course – LS – NPI EA (cat=REST)

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

eBook Jackson – NPI EA – 3 (cat = Jackson)