Home/Learn/Hibernate & JPA/Schema Generation (hbm2ddl)

Schema Generation (hbm2ddl)

Intermediate
Advanced

spring.jpa.hibernate.ddl-auto controls schema generation: validate (production), update (development), create-drop (tests); use Flyway or Liquibase for production migrations.

Overview

Hibernate's DDL auto feature (hbm2ddl.auto) can generate, update, validate, or drop/recreate the database schema from JPA entity mappings at startup. In development it is convenient; in production it is dangerous — update mode can silently drop columns or leave orphaned tables, and neither mode provides rollback capability, version history, or team collaboration. The industry-standard approach is to set ddl-auto=validate in production (ensuring the DB schema matches entity mappings without modifying anything) and manage all schema changes with a migration tool (Flyway or Liquibase). These tools version-control SQL scripts, apply them in order, and prevent the same script from running twice, enabling safe automated deployments and rollbacks.

ddl-auto modes and when to use them

Each mode has specific use-cases. Using the wrong mode in the wrong environment is a common source of data loss or startup failures.

Properties — ddl-auto mode reference
# application.properties

# PRODUCTION: validate entity mappings against existing schema, fail fast if mismatch
spring.jpa.hibernate.ddl-auto=validate

# DEVELOPMENT: let Hibernate update schema (adds columns, creates tables)
# WARNING: never on production — update can drop NOT NULL or rename incorrectly
spring.jpa.hibernate.ddl-auto=update

# TESTING: drop and recreate schema before each test run
spring.jpa.hibernate.ddl-auto=create-drop

# CI/TESTING ALTERNATIVE: create schema fresh (no drop on close)
spring.jpa.hibernate.ddl-auto=create

# NONE: disable Hibernate DDL entirely (use with Flyway/Liquibase)
spring.jpa.hibernate.ddl-auto=none

# Show generated DDL (useful during development)
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

# Export Hibernate-generated DDL to file without executing
spring.jpa.properties.javax.persistence.schema-generation.scripts.action=create
spring.jpa.properties.javax.persistence.schema-generation.scripts.create-target=schema.sql

Flyway for production schema migrations

Flyway versioned migrations are the standard for production. Scripts in src/main/resources/db/migration are applied in version order exactly once. Spring Boot auto-configures Flyway when it is on the classpath.

XML + SQL — Flyway migration setup
<!-- pom.xml -->
<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-core</artifactId>
</dependency>
<!-- For MySQL 8+ -->
<dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-mysql</artifactId>
</dependency>

# application.properties — Flyway config
spring.flyway.enabled=true
spring.flyway.baseline-on-migrate=true   # first run on existing DB
spring.flyway.locations=classpath:db/migration
spring.jpa.hibernate.ddl-auto=validate   # Flyway handles DDL, Hibernate validates

# Migration files: src/main/resources/db/migration/
# V1__create_orders_table.sql
CREATE TABLE orders (
    id         BIGINT       NOT NULL AUTO_INCREMENT,
    customer_id BIGINT      NOT NULL,
    status     VARCHAR(30)  NOT NULL DEFAULT 'PENDING',
    total      DECIMAL(10,2) NOT NULL,
    created_at TIMESTAMP    NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    INDEX idx_customer (customer_id)
);

# V2__add_order_reference.sql
ALTER TABLE orders ADD COLUMN reference VARCHAR(50) UNIQUE;

# V3__add_items_table.sql
CREATE TABLE order_items ( ... );

Generating Flyway baseline migration from entities

A common workflow: let Hibernate generate the initial DDL from entities, then hand it to Flyway as V1. Use the ddl export property to capture the SQL without executing it.

Properties + Java — DDL export + Flyway baseline workflow
# Step 1: export Hibernate DDL to file (no DB execution)
# application-ddl-export.properties
spring.jpa.hibernate.ddl-auto=none
spring.datasource.url=jdbc:h2:mem:testdb
spring.jpa.properties.javax.persistence.schema-generation.scripts.action=create
spring.jpa.properties.javax.persistence.schema-generation.create-source=metadata
spring.jpa.properties.javax.persistence.schema-generation.scripts.create-target=  src/main/resources/db/migration/V1__initial_schema.sql

# Step 2: review generated SQL, clean it up, add indexes
# Step 3: set spring.flyway.baseline-on-migrate=true for first deploy

# Useful: validate Flyway + Hibernate consistency in tests
@SpringBootTest
@Testcontainers
class SchemaConsistencyTest {
    @Container
    static MySQLContainer<?> mysql = new MySQLContainer<>("mysql:8");

    @Test
    void flywayAndHibernateSchemaShouldMatch() {
        // If Flyway runs cleanly AND Hibernate validates (ddl-auto=validate)
        // without exception, schemas are consistent.
        // Spring Boot test context startup itself is the assertion.
    }
}

Key Points to Remember

  • 1Never use ddl-auto=update or create-drop in production — use validate or none only.
  • 2Flyway (or Liquibase) version-controls schema changes, enables rollbacks, and prevents double-application of scripts.
  • 3Spring Boot auto-configures Flyway; add flyway-core to pom.xml and put scripts in db/migration.
  • 4Naming convention: V{version}__{description}.sql — double underscore, no spaces.
  • 5Use baseline-on-migrate=true when introducing Flyway to an existing database.
  • 6Testcontainers + Flyway in tests gives you a real DB migration smoke test on every build.

Interview Questions

Sign in to ask Aria
1

Why is ddl-auto=update dangerous in production even though it seems convenient?

EasyNetflix
2

How does Flyway track which migrations have already been applied?

EasyAmazon
3

What is the difference between Flyway versioned (V) and repeatable (R) migration scripts?

MediumShopify
4

How would you safely add a NOT NULL column to a large production table without downtime?

HardUber
5

How do you validate that your Flyway migrations and JPA entity mappings are consistent?

MediumZalando

Ask Aria about Schema Generation (hbm2ddl)

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…