Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/spring-projects/spring-boot/llms.txt

Use this file to discover all available pages before exploring further.

Spring Boot supports multiple strategies for initializing a database on startup—from simple SQL scripts to full migration tools like Flyway and Liquibase. Choosing the right approach depends on your database type, environment, and whether you need versioned, repeatable migrations. This guide walks you through each strategy with concrete configuration examples.
Use a single initialization mechanism. Mixing schema.sql/data.sql scripts with Flyway or Liquibase is not recommended and support for combining them will be removed in a future release.

Run schema.sql and data.sql on startup

Spring Boot automatically loads schema scripts from optional:classpath*:schema.sql and data scripts from optional:classpath*:data.sql at startup.
application.yaml
spring:
  sql:
    init:
      mode: always        # always | embedded | never
      schema-locations: "classpath:db/schema.sql"
      data-locations: "classpath:db/data.sql"
The optional: prefix (present by default) means startup succeeds even when the files are absent. Remove it to fail fast on missing scripts. By default, SQL initialization only runs against embedded in-memory databases. Set spring.sql.init.mode=always to run scripts against any database type, or never to disable initialization entirely.
Initialization scripts support -- for single-line comments and /* */ for block comments. Other comment formats are not supported.
To run platform-specific scripts, set spring.sql.init.platform. Spring Boot then processes schema-${platform}.sql and data-${platform}.sql files:
application.yaml
spring:
  sql:
    init:
      platform: postgresql

Use Flyway for migrations

Flyway provides versioned, repeatable database migrations with audit history. Follow these steps to set it up:
1

Add the Flyway starter

Add spring-boot-starter-flyway to your project. For database-specific features, also add the matching Flyway module:
pom.xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-flyway</artifactId>
</dependency>
<!-- Required for PostgreSQL-specific features -->
<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-database-postgresql</artifactId>
</dependency>
2

Create migration scripts

Place versioned migration scripts in src/main/resources/db/migration. Name them using the pattern V<VERSION>__<NAME>.sql, where <VERSION> is an underscore-separated version number:
V1__create_users_table.sql
CREATE TABLE users (
    id   BIGINT PRIMARY KEY,
    name VARCHAR(255) NOT NULL
);
V2__add_email_column.sql
ALTER TABLE users ADD COLUMN email VARCHAR(255);
3

Configure migration locations

By default, Flyway looks in classpath:db/migration. Customize the location or add multiple paths using spring.flyway.locations:
application.yaml
spring:
  flyway:
    locations: "classpath:db/migration,filesystem:/opt/migration"
Use the {vendor} placeholder to switch to database-specific directories automatically:
application.yaml
spring:
  flyway:
    locations: "classpath:db/migration/{vendor}"
With this setting, Flyway uses db/migration/postgresql for PostgreSQL, db/migration/mysql for MySQL, and so on.
4

Configure Flyway behavior

Control whether Flyway validates the migration checksum on startup and other common options:
application.yaml
spring:
  flyway:
    enabled: true
    validate-on-migrate: true
    baseline-on-migrate: false
    out-of-order: false
5

Use a dedicated Flyway DataSource (optional)

By default, Flyway uses the auto-configured primary DataSource. To point Flyway at a separate database, set its connection properties directly:
application.yaml
spring:
  flyway:
    url: "jdbc:postgresql://migrations-host/mydb"
    user: "flyway_user"
    password: "flyway_pass"
Setting either spring.flyway.url or spring.flyway.user is sufficient to make Flyway use its own DataSource. Any unset property falls back to the equivalent spring.datasource.* value.
Flyway also supports Java-based migrations. Any bean implementing JavaMigration is automatically registered with Flyway.

Use Liquibase for migrations

Add spring-boot-starter-liquibase to your classpath. Liquibase runs automatically during application startup and before tests:
pom.xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-liquibase</artifactId>
</dependency>
By default, Liquibase reads the master changelog from db/changelog/db.changelog-master.yaml. Configure the path with spring.liquibase.change-log:
application.yaml
spring:
  liquibase:
    change-log: "classpath:db/changelog/db.changelog-master.yaml"
    enabled: true
Liquibase supports YAML, JSON, XML, and SQL changelog formats. A YAML changelog looks like this:
db.changelog-master.yaml
databaseChangeLog:
  - changeSet:
      id: 1
      author: alice
      changes:
        - createTable:
            tableName: users
            columns:
              - column:
                  name: id
                  type: BIGINT
                  constraints:
                    primaryKey: true
              - column:
                  name: name
                  type: VARCHAR(255)
To use a separate DataSource for Liquibase, set its connection properties directly:
application.yaml
spring:
  liquibase:
    url: "jdbc:postgresql://migrations-host/mydb"
    user: "liquibase_user"
    password: "liquibase_pass"
It is not possible to use two different initialization mechanisms for the same environment—for example, Liquibase for the application and JPA DDL for tests. Use the spring.liquibase.enabled property with Spring profiles to control this.

Initialize a Spring Batch database

Spring Batch ships pre-packaged SQL scripts for most database platforms. Spring Boot auto-detects the database type and runs those scripts. For embedded databases this happens by default. Enable it for any database type:
application.yaml
spring:
  batch:
    jdbc:
      initialize-schema: "always"   # always | embedded | never

Use test-only migrations

Place test-specific migration scripts in src/test/resources/db/migration. These files are executed after production migrations but only when running tests. They are not packaged in the application jar.Example test data script:
src/test/resources/db/migration/V9999__test-data.sql
INSERT INTO users (id, name) VALUES (1, 'Alice Test');
INSERT INTO users (id, name) VALUES (2, 'Bob Test');
You can also use profile-specific locations to run certain migrations only when a particular Spring profile is active. In application-dev.yaml:
application-dev.yaml
spring:
  flyway:
    locations: "classpath:/db/migration,classpath:/dev/db/migration"

Control initialization order

Spring Boot automatically detects beans that initialize a database and beans that depend on initialization, and configures the dependency chain accordingly. The following types are detected as database initializers:
  • DataSourceScriptDatabaseInitializer
  • EntityManagerFactory
  • Flyway / FlywayMigrationInitializer
  • R2dbcScriptDatabaseInitializer
  • SpringLiquibase
The following types are detected as depending on initialization:
  • AbstractEntityManagerFactoryBean
  • DSLContext (jOOQ)
  • JdbcClient
  • JdbcOperations
  • NamedParameterJdbcOperations
If your application tries to access the database during startup before initialization completes, annotate the bean’s class or @Bean method with @DependsOnDatabaseInitialization to register it in the dependency chain. To have a custom third-party initializer detected automatically, register an implementation of DatabaseInitializerDetector in META-INF/spring.factories.
If you use Hibernate and also want to run data.sql after Hibernate creates the schema, set spring.jpa.defer-datasource-initialization=true. This defers script-based initialization until after all EntityManagerFactory beans are created.

Build docs developers (and LLMs) love