Spring Boot
data.sql
Profiles
Application Configuration
Database Initialization

Spring-Boot execute data.sql in one profile only

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

If you want Spring Boot to run seed data in only one profile, the clean solution is to make SQL initialization profile-specific rather than trying to hide conditional logic inside data.sql. In current Spring Boot versions, that usually means using profile-specific configuration with spring.sql.init.* properties and pointing the desired profile at its own SQL file.

Why the Default data.sql Is Too Broad

A plain data.sql in src/main/resources is classpath-wide. If SQL initialization is enabled, Spring Boot will try to use it regardless of whether you intended it only for dev, local, or test.

That is a problem when seed data should exist in one environment but not in another. You do not want demo users or fake lookup rows appearing in production by accident.

So instead of one global data.sql, use:

  • no global seed file by default
  • profile-specific SQL file names such as data-dev.sql
  • profile-specific spring.sql.init.data-locations

A Simple Profile-Specific Setup

Start with a neutral base configuration.

yaml
1# application.yml
2spring:
3  sql:
4    init:
5      mode: never

Then enable SQL initialization only in the profile where you want it.

yaml
1# application-dev.yml
2spring:
3  sql:
4    init:
5      mode: always
6      data-locations: classpath:data-dev.sql

Now when the dev profile is active, Spring Boot loads data-dev.sql. When other profiles are active, SQL seeding stays off.

Example SQL File

The SQL file itself remains ordinary SQL.

sql
1INSERT INTO app_user (id, username, role)
2VALUES (1, 'demo', 'ADMIN');
3
4INSERT INTO app_user (id, username, role)
5VALUES (2, 'tester', 'USER');

The important part is not the file content. It is that the file is only referenced by the intended profile.

Running with the Profile

You can activate the profile in several ways. One common option is the command line.

bash
java -jar app.jar --spring.profiles.active=dev

During startup, Spring Boot uses application-dev.yml, sees that SQL initialization is enabled, and runs the configured script.

For production, omit that profile or activate a different one:

bash
java -jar app.jar --spring.profiles.active=prod

In that case, the base configuration keeps SQL seeding disabled.

When You Need Schema and Data Together

If the profile should also create schema objects, configure both schema and data locations for that profile.

yaml
1spring:
2  sql:
3    init:
4      mode: always
5      schema-locations: classpath:schema-dev.sql
6      data-locations: classpath:data-dev.sql

That keeps the whole initialization path scoped to the intended environment.

An Alternative: Custom Initializer Bean

If the condition is more complex than profile matching, you can create a small Spring bean that runs SQL only when a certain profile is active.

java
1import javax.sql.DataSource;
2import org.springframework.context.annotation.Bean;
3import org.springframework.context.annotation.Configuration;
4import org.springframework.context.annotation.Profile;
5import org.springframework.core.io.ClassPathResource;
6import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
7
8@Configuration
9public class SqlInitConfig {
10
11    @Bean
12    @Profile("dev")
13    public ResourceDatabasePopulator devPopulator(DataSource dataSource) {
14        ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
15        populator.addScript(new ClassPathResource("data-dev.sql"));
16        populator.execute(dataSource);
17        return populator;
18    }
19}

This works, but it is usually more verbose than using spring.sql.init.*. Prefer configuration properties unless you truly need code-level control.

When to Use Flyway or Liquibase Instead

For small seed datasets, profile-specific SQL init is fine. For serious schema evolution and repeatable data migrations, Flyway or Liquibase is often the better tool.

Those tools give you versioning, ordering, and deployment discipline. Spring Boot's automatic SQL init is convenient, but it is not meant to replace full migration management in a complex application.

A common pattern is:

  • Flyway for schema and durable migrations
  • profile-scoped SQL init only for local development seed data

That division keeps things predictable.

Common Pitfalls

A common mistake is leaving a global data.sql on the classpath while also trying to add profile-specific behavior. The global file can still run if initialization is enabled.

Another issue is using old configuration keys from older Spring Boot versions. Current Boot uses spring.sql.init.*, so copying outdated spring.datasource.initialization-mode examples can lead to confusion.

Teams also sometimes seed production accidentally because the wrong profile is active in deployment. Treat profile selection as part of deployment safety, not as an afterthought.

Finally, do not use ad hoc startup SQL for long-term schema migration strategy. That is where dedicated migration tools are better.

Summary

  • Use profile-specific configuration to control when seed SQL runs.
  • Keep SQL init disabled by default and enable it only in the intended profile.
  • Point spring.sql.init.data-locations at a profile-specific SQL file.
  • Prefer spring.sql.init.* properties over older deprecated configuration styles.
  • Use Flyway or Liquibase when the problem is migration management, not simple seeding.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.