Spring Boot. DataJpaTest H2 embedded database create schema
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
@DataJpaTest is designed to load a narrow Spring test slice focused on JPA repositories, and it commonly pairs with an embedded H2 database. The usual question is not whether H2 works, but how the schema gets created for the test. In practice, Spring Boot can create that schema from JPA entity metadata, from SQL scripts, or from migration tools, and the test should choose one path deliberately.
What @DataJpaTest Sets Up
A minimal repository test often looks like this:
By default, @DataJpaTest configures repository infrastructure and commonly replaces the normal datasource with an embedded test database if one is available.
Schema from JPA Entities
If you want Hibernate to create the schema directly from the entity mappings, set the DDL mode accordingly.
With H2, this is often enough for repository tests. Spring Boot starts the in-memory database, Hibernate inspects the entities, creates the tables, and drops them again when the test context closes.
This is the easiest path when:
- the entity mappings are the source of truth
- you do not need vendor-specific SQL behavior
- you want fast isolated repository tests
Schema from SQL Scripts
Sometimes the test schema should come from SQL files instead of generated DDL. In that case, place scripts such as schema.sql and optionally data.sql in the test resources and make sure SQL initialization is enabled when needed.
Example schema.sql:
This is useful when the test must mirror a specific schema shape instead of whatever Hibernate currently derives from the entities.
Avoid Mixing Competing Schema Strategies by Accident
A frequent source of confusion is enabling multiple schema-creation paths at once, for example:
- '
ddl-auto=create-drop' - '
schema.sql' - Flyway or Liquibase migrations
If more than one mechanism is active, you can get duplicate creation attempts or test behavior that is hard to reason about. Repository tests are much easier to maintain when one schema source is chosen explicitly.
Control Whether the Test Uses H2 or the Real Database Type
By default, @DataJpaTest often swaps in an embedded test database. If that is not what you want, disable the replacement.
This is useful when the repository logic depends on behavior that H2 does not model well enough compared with the production database.
Use Test Properties to Keep the Setup Explicit
A test-specific properties file often makes the setup clearer.
This gives the test slice a predictable database and makes the schema strategy visible in one place.
Know What You Are Actually Testing
If the goal is repository logic and JPA mappings, generated schema in H2 is often enough. If the goal is to validate exact DDL, SQL dialect, indexes, or migration scripts, an in-memory H2 database may not be representative enough.
That is the main architectural question behind many @DataJpaTest problems: do you want a fast repository test or a database-faithful integration test? Those are related but different goals.
Common Pitfalls
- Assuming
@DataJpaTestalways creates the schema automatically without checking the configured strategy. - Enabling both Hibernate DDL generation and SQL scripts without intending to.
- Forgetting that H2 may not behave exactly like the production database dialect.
- Letting the embedded test database replace the real datasource when the test needed the production database type.
- Treating schema generation and test data loading as if they were the same configuration problem.
Summary
- '
@DataJpaTestcommonly works with H2 for fast repository-focused tests.' - The schema can be created from JPA entities, SQL scripts, or migration tools.
- '
spring.jpa.hibernate.ddl-auto=create-dropis the usual generated-schema choice.' - Pick one schema-creation path deliberately instead of mixing several.
- If dialect fidelity matters more than speed, H2 may not be the right test database.
Related reading
- Spring boot ddl auto generator
- Spring Boot default H2 jdbc connection and H2 console
- Spring boot doesn't load data to initialize database using data.sql
- Spring boot fails to load DataSource using PostgreSQL driver
- Spring Boot default proxying mechanism
- Spring Boot default test throws an IllegalStateException
- Spring Boot Getting Scheduled cron value from database
- Spring Boot Hibernate and Flyway boot order

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.