Spring boot doesn't load data to initialize database using data.sql
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
When data.sql is ignored in a Spring Boot application, the root cause is usually startup order, not the SQL file itself. Spring Boot only runs initialization scripts under specific conditions, and those conditions changed across recent Spring Boot releases.
How data.sql Is Supposed To Run
Spring Boot can initialize a database from SQL scripts placed in src/main/resources. The common convention is:
- '
schema.sqlcreates tables' - '
data.sqlinserts rows'
For an embedded database such as H2, this often works with no extra settings. For an external database such as PostgreSQL or MySQL, Boot may skip initialization unless you opt in.
A minimal example looks like this:
And then:
If the application starts and the table exists before the script runs, the rows should be inserted automatically.
The Most Common Cause: JPA Creates Tables Too Late
A frequent failure mode appears when Hibernate generates the schema, but data.sql runs before Hibernate has created the tables. In that case the inserts fail silently in logs you may not be watching, or the application aborts during startup.
For Spring Boot 2.5 and later, the usual fix is:
That property tells Boot to wait until JPA has finished schema creation before running data.sql.
If you also want Hibernate to create the schema automatically in development, pair it with a JPA setting like this:
Without the defer setting, data.sql may target tables that do not exist yet.
External Databases Need Explicit Initialization
Another common confusion is that Boot behaves differently for embedded and non-embedded databases. H2 and HSQLDB are often initialized by default during local development, but PostgreSQL and MySQL typically require this:
If you leave the default behavior in place, Boot may decide not to run data.sql at all. That makes the application look like it ignored the script even though the framework was following its initialization rules.
Verify File Placement And Naming
The SQL files must be on the application classpath. The standard location is:
Small mistakes matter here:
- '
Data.sqlinstead ofdata.sql' - placing the file in
src/test/resources - putting it in a nested directory without configuring a custom location
If you want a custom script location, declare it explicitly:
Watch Out For Flyway And Liquibase
If your application uses Flyway or Liquibase, those tools usually become the source of truth for schema and seed data. Mixing them casually with schema.sql and data.sql can produce confusing startup order or duplicated inserts.
A cleaner rule is:
- use
schema.sqlanddata.sqlfor small local setups - use Flyway or Liquibase for versioned schema changes in real deployments
If Flyway is active, seed data is usually better placed in a migration such as V2__seed_users.sql rather than in data.sql.
A Small End-To-End Example
Here is a minimal entity and repository-backed setup that works with H2.
In this arrangement, schema.sql creates the table and data.sql inserts rows. That is usually simpler than asking Hibernate to create the table unless you specifically want JPA-driven schema generation.
How To Debug It Quickly
Enable SQL initialization logs so you can see whether Spring Boot found and executed the script:
If Boot logs that it skipped initialization, the problem is configuration. If it logs SQL errors, the file was found and the problem is schema mismatch or ordering.
Common Pitfalls
- Expecting
data.sqlto run against PostgreSQL or MySQL withoutspring.sql.init.mode=always. - Letting Hibernate create tables but forgetting
spring.jpa.defer-datasource-initialization=true. - Placing
data.sqloutsidesrc/main/resources. - Using table names in
data.sqlthat do not match the actual generated schema. - Mixing Flyway or Liquibase with Boot SQL initialization without a clear ownership rule.
Summary
- '
data.sqlproblems are usually caused by initialization order or Boot configuration.' - For external databases, set
spring.sql.init.mode=always. - If JPA creates tables, add
spring.jpa.defer-datasource-initialization=true. - Keep
data.sqlon the classpath and confirm the file name exactly. - Turn on SQL init debug logging to distinguish a skipped script from a failing script.
Related reading
- Spring boot fails to load DataSource using PostgreSQL driver
- Spring Boot Getting Scheduled cron value from database
- Spring Boot Hibernate and Flyway boot order
- Spring Boot JPA2 Hibernate - enable second level cache
- Spring Boot embedded HornetQ cluster not forwarding messages
- Spring Boot enable http requests logging access logs
- Spring boot errorjava.lang.ArrayStoreException sun.reflect.annotation.TypeNotPresentExceptionProxy
- Spring Boot fails to run maven-surefire-plugin ClassNotFoundException org.apache.maven.surefire.booter.ForkedBooter

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack 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.