Question
Hibernate hbm2ddl.auto Values Explained: validate, update, create, create-drop, and schema strategies
Question
I want to understand the possible values for the Hibernate hbm2ddl.auto configuration, especially update and export, and what each option actually does.
I also want to know when update should be used, when it should be avoided, and what the safer alternatives are.
For example, how should schema changes be handled in cases like these?
- creating new tables
- adding new columns to existing tables
- deleting columns
- changing a column's data type
- changing a column's attributes
- dropping tables
- changing the values stored in a column
For each case, what is the best approach?
Short Answer
By the end of this page, you will understand what hibernate.hbm2ddl.auto does, what each common value means, when update is convenient, and why production systems usually use migration tools instead. You will also see how different database changes—such as adding columns, removing tables, or changing data types—should be handled safely.
Concept
hibernate.hbm2ddl.auto is a Hibernate configuration setting that controls how Hibernate interacts with your database schema when the application starts.
In simple terms, it answers this question:
Should Hibernate only check the schema, try to modify it, recreate it, or do nothing?
Common values include:
validateupdatecreatecreate-dropnoneor leaving it unset, depending on setup
Older documentation and discussions may also mention export. In practice, developers usually talk about the actions above, while schema generation may also be handled through JPA schema-generation settings or external migration tools.
Why this matters
Your Java entity classes and your database schema must stay in sync.
For example, if your entity has:
@Column(nullable = false)
private String email;
but the database table does not have an email column, your application may fail or behave incorrectly.
Hibernate can help with this mismatch, but how much help it gives depends on the hbm2ddl.auto value.
What each value means
validate
Hibernate checks whether the database schema matches the entity mappings.
- It does not create tables
- It does not change columns
- It fails startup if the schema is incompatible
Good for:
- production environments
- CI environments
- teams that manage schema changes explicitly
update
Hibernate tries to update the schema to match the entities.
Typical behavior:
- may create missing tables
- may add missing columns
- may create some constraints/indexes depending on dialect and mapping
- usually does not safely handle destructive or complex changes
Important limitation:
- it is not a full database migration system
- it is not reliable for controlled production schema evolution
Good for:
- local development
- prototypes
- quick experiments
create
Hibernate drops the existing schema and recreates it when the application starts.
Good for:
- temporary test databases
- demos
- disposable environments
Danger:
- existing data is lost
create-drop
Hibernate creates the schema at startup and drops it when the session factory or application shuts down.
Good for:
- automated tests
- in-memory databases
Danger:
- not suitable for persistent data
none or unset
Hibernate does not attempt schema generation.
Good for:
- production systems using Flyway or Liquibase
- systems where DBAs or scripts manage schema changes
The key idea
hbm2ddl.auto is for schema generation/checking, not for carefully planned database migrations.
That distinction is the reason update is often acceptable in development but discouraged in production.
Mental Model
Think of your database schema as a building, and your entity classes as the blueprint.
validate= an inspector checks whether the building matches the blueprintupdate= a handyman tries to make small adjustments to the buildingcreate= the building is demolished and rebuilt from scratchcreate-drop= the building is built for a short event and torn down afterward- migration tools = a licensed construction team follows a written renovation plan, step by step
This analogy helps explain why update is risky for serious changes.
A handyman can add a shelf or install a door, but if you need to remove load-bearing walls or change plumbing, you want a detailed plan. Database migrations work the same way.
Syntax and Examples
The property is usually configured in application.properties, application.yml, persistence.xml, or Hibernate configuration.
Example in Spring Boot properties
spring.jpa.hibernate.ddl-auto=validate
Common values:
spring.jpa.hibernate.ddl-auto=none
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.ddl-auto=create
spring.jpa.hibernate.ddl-auto=create-drop
Example in Hibernate configuration
hibernate.hbm2ddl.auto=update
Example entity
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
@Entity
public class UserAccount {
@Id
private Long id;
@Column(nullable = false)
private String username;
private String email;
}
If the database is missing the UserAccount table:
- with
create, Hibernate recreates the schema - with
create-drop, Hibernate creates it temporarily - with
update, Hibernate may create the missing table - with
validate, startup fails - with
none, Hibernate does nothing
Beginner-friendly recommendation
Use this as a starting point:
- local development:
updateor sometimescreate-drop - automated tests:
create-drop - production:
validateornoneplus Flyway/Liquibase
About export
You may see references to schema export in older Hibernate discussions. The practical lesson is this:
- schema export/creation is for generating schema from mappings
hbm2ddl.autocontrols whether Hibernate validates, updates, creates, or drops schema automatically
In modern projects, explicit migrations are preferred for production changes.
Step by Step Execution
Consider this entity:
@Entity
public class Product {
@Id
private Long id;
private String name;
}
Assume the database currently has no Product table.
What happens with update
Startup flow:
- Hibernate reads the entity mappings.
- Hibernate inspects the current database schema.
- It notices that the
Producttable is missing. - It generates SQL to create the missing table.
- The application starts.
A simplified idea of the SQL might be:
create table product (
id bigint not null,
name varchar(255),
primary key (id)
);
What happens with validate
Startup flow:
- Hibernate reads the entity mappings.
- Hibernate inspects the current database schema.
- It notices that the
Producttable is missing. - It throws an error.
- The application does not start.
What happens with create
Startup flow:
- Hibernate drops existing schema objects it manages.
- Hibernate recreates them from entity mappings.
- Existing data is lost.
- The application starts with a fresh schema.
Small change example
Now change the entity:
@Entity
public class Product {
@Id
private Long id;
private String name;
private String description;
}
If the description column does not exist:
updatemay add the new columnvalidatewill fail until the column existscreatewill rebuild the table from scratch
This shows the main pattern:
updatetries to fix missing piecesvalidatechecks onlycreateresets everything
Real World Use Cases
1. Local development
A developer adds a new entity field while building a feature.
private String phoneNumber;
Using update can quickly add the new column in a local database so development can continue.
2. Automated integration tests
A test suite needs a fresh schema on every run.
Use create-drop with an in-memory database like H2 so each test run starts clean.
3. Production deployment
A team needs to add a non-null column to a large customer table without breaking running systems.
They should use a migration script tool such as Flyway or Liquibase, not update.
4. Startup safety checks
A production app should fail fast if the schema is wrong.
Use validate so deployment fails early when database and entity mappings are out of sync.
5. Prototype or demo apps
A throwaway app can use create or update for speed, because preserving data is not important.
Real Codebase Usage
In real projects, teams rarely rely on update in production.
Common production pattern
- Hibernate setting:
validateornone - Schema changes: Flyway or Liquibase
- Deployment pipeline: migration runs before app startup
Why teams do this
Migration tools provide:
- versioned SQL scripts
- reviewable schema changes
- repeatable deployments
- rollback planning
- data transformation support
- team visibility into what changed
Common patterns in codebases
Guarding startup with validate
Developers use validate to ensure mappings still match the database.
Explicit migrations for risky changes
Examples:
- renaming columns
- splitting one column into two
- converting
varchartoint - dropping tables
- backfilling data
These changes need hand-written SQL or controlled migration scripts.
Environment-specific configuration
A common setup is:
# application-dev.properties
spring.jpa.hibernate.ddl-auto=update
# application-test.properties
spring.jpa.hibernate.ddl-auto=create-drop
# application-prod.properties
spring.jpa.hibernate.ddl-auto=validate
Data migration separated from schema migration
Changing stored values is not really a schema-generation task.
For example:
update customer
set status = 'ACTIVE'
where status = 'A';
That belongs in a migration script, not in hbm2ddl.auto.
Common Mistakes
Mistake 1: Using update in production and assuming it is safe
update is convenient, but it is not a complete migration solution.
It may handle simple additions, but it is not ideal for destructive or complex changes.
Better approach
- use Flyway or Liquibase for schema changes
- use
validatein production
Mistake 2: Expecting update to remove old columns or tables
Beginners often assume Hibernate will fully synchronize the database with entities.
Broken expectation:
// Column removed from entity
// Beginner expects DB column to disappear automatically
In practice, Hibernate usually avoids dangerous destructive changes automatically.
Better approach
Write an explicit migration:
alter table users drop column old_field;
Mistake 3: Using create on a database with important data
spring.jpa.hibernate.ddl-auto=create
This can wipe existing schema and data.
Better approach
Use validate in production and create only for disposable databases.
Mistake 4: Treating data changes like schema changes
Changing values inside rows is different from changing table structure.
Broken idea:
- “I changed an enum name in Java, so Hibernate will update all old database values.”
Usually it will not.
Better approach
Use explicit SQL migration scripts for data updates.
Mistake 5: Ignoring nullable/default constraints when adding columns
Adding a new non-null column to a table with existing rows can fail.
Example:
@Column(nullable = false)
private String country;
If old rows already exist, the database needs a value for them.
Better approach
Use staged migration steps:
- add the column as nullable or with a default
- backfill existing rows
- make the column non-null
Mistake 6: Renaming a field and expecting automatic rename behavior
If you change:
private String fullName;
to:
private String displayName;
Hibernate may interpret this as:
- add new column
- leave old column in place
not as a true rename.
Better approach
Use an explicit migration:
alter table users rename column full_name to display_name;
Comparisons
| Option | What it does | Good for | Risk level | Production fit |
|---|---|---|---|---|
none | Does nothing | Fully manual schema management | Low | Excellent |
validate | Checks schema matches mappings | Production safety checks | Low | Excellent |
update | Tries to apply simple schema changes | Local development | Medium | Usually poor |
create | Recreates schema at startup | Disposable databases | Very high | No |
create-drop | Creates at startup, drops at shutdown | Tests | Very high | No |
update vs migration tools
| Aspect | update | Flyway/Liquibase |
|---|---|---|
| Adds tables/columns | Often yes | Yes |
| Drops columns/tables safely | Usually not reliable | Yes, explicitly |
| Renames columns | Usually no | Yes |
| Data migrations | No practical support | Yes |
| Version history | No | Yes |
| Reviewable by team | Limited | Yes |
| Production safety | Limited | Much better |
Best approach for the listed change types
| Change type | Use update? | Best solution |
|---|---|---|
| New tables | Sometimes in dev | Migration script in shared/prod environments |
| New columns in old tables | Sometimes in dev | Migration script, especially if constraints exist |
| Columns deleted | No | Explicit migration |
| Data type changed | No | Explicit migration with data handling |
| Column attributes changed | Usually no | Explicit migration |
| Tables dropped | No | Explicit migration |
| Values of a column changed | No | Data migration script |
The pattern is simple:
- simple additive changes may work with
updatein development - destructive or data-sensitive changes should use migrations
Cheat Sheet
# Common Hibernate / Spring Boot schema options
spring.jpa.hibernate.ddl-auto=none
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.ddl-auto=create
spring.jpa.hibernate.ddl-auto=create-drop
Quick meanings
none: do nothingvalidate: check schema onlyupdate: try to add/fix simple schema differencescreate: drop and recreate schema on startupcreate-drop: create on startup, drop on shutdown
Safe defaults
- Development:
update - Testing:
create-drop - Production:
validateornone
When not to use update
Avoid update for:
- dropping columns
- dropping tables
- renaming columns
- changing data types
- changing existing data values
- complex constraint changes
Better alternative
Use a migration tool:
- Flyway
- Liquibase
Rule of thumb
- If data must be preserved carefully, use migrations.
- If the database is disposable, Hibernate auto-DDL can be fine.
Important edge case
Adding a non-null column to a table with existing rows often requires:
- add column nullable or with default
- fill existing data
- add non-null constraint
FAQ
What is hibernate.hbm2ddl.auto used for?
It controls whether Hibernate validates, updates, creates, or drops the database schema based on your entity mappings.
Is hibernate.hbm2ddl.auto=update safe in production?
Usually no. It can be acceptable for small internal apps, but most production systems should use migration tools and keep Hibernate on validate or none.
What is the difference between validate and update?
validate only checks whether the schema matches. update tries to modify the schema to match the entities.
Will update delete unused columns or tables?
Usually you should not rely on it for that. Destructive changes should be done with explicit migration scripts.
Should I use create or create-drop in production?
No. They are intended for disposable databases, tests, and temporary environments because they can destroy data.
How should I change column data types safely?
Use a migration script. Data type changes can require data conversion, validation, and rollback planning.
How do I update values already stored in a column?
Use a data migration SQL script or a migration tool. hbm2ddl.auto is about schema management, not row-by-row data correction.
What is the best alternative to update?
For real applications, use Flyway or Liquibase to manage versioned schema changes explicitly.
Mini Project
Description
Build a small Spring Boot configuration example that uses different schema strategies for development, testing, and production. This project demonstrates the practical way teams use Hibernate schema settings safely across environments.
Goal
Create environment-specific Hibernate schema configuration and understand why production uses validation instead of automatic updates.
Requirements
- Create separate configuration for development, test, and production environments.
- Use
updatefor development,create-dropfor testing, andvalidatefor production. - Add one example entity such as
Customer. - Show one SQL migration that adds a new column safely.
- Explain which part is handled by Hibernate and which part is handled by migrations.
Keep learning
Related questions
Add External JAR Files to an IntelliJ IDEA Java Project
Learn how to add external JAR dependencies to an IntelliJ IDEA Java project using module libraries, and when to use Maven or Gradle instead.
Avoiding Java Code in JSP with JSP 2: EL and JSTL Explained
Learn how to avoid Java scriptlets in JSP 2 using Expression Language and JSTL, with examples, best practices, and common mistakes.
Call a Method After a Delay in Android Java
Learn how to run Java code after a delay in Android using Handler.postDelayed, manage the main thread, and cancel callbacks safely.