1242

I really want to know more about the update, export and the values that could be given to hibernate.hbm2ddl.auto
I need to know when to use the update and when not? And what is the alternative?

These are changes that could happen over DB:

  • new tables
  • new columns in old tables
  • columns deleted
  • data type of a column changed
  • a type of a column changed its attributes
  • tables dropped
  • values of a column changed

In each case what is the best solution?

Vlad Mihalcea
  • 142,745
  • 71
  • 566
  • 911

14 Answers14

1215

From the community documentation:

hibernate.hbm2ddl.auto Automatically validates or exports schema DDL to the database when the SessionFactory is created. With create-drop, the database schema will be dropped when the SessionFactory is closed explicitly.

e.g. validate | update | create | create-drop

So the list of possible options are,

  • validate: validate the schema, makes no changes to the database.
  • create-only: database creation will be generated.
  • drop: database dropping will be generated.
  • update: update the schema.
  • create: creates the schema, destroying previous data.
  • create-drop: drop the schema when the SessionFactory is closed explicitly, typically when the application is stopped.
  • none: does nothing with the schema, makes no changes to the database

These options seem intended to be developers tools and not to facilitate any production level databases, you may want to have a look at the following question; Hibernate: hbm2ddl.auto=update in production?

Marc Bannout
  • 388
  • 4
  • 15
James McMahon
  • 48,506
  • 64
  • 207
  • 283
  • 15
    Just read the hibernate docu ... for valid values, it says: "e.g." ... are there any other valid values? – Ta Sas Jul 10 '10 at 22:20
  • 1
    Not that I am aware of. They could be misusing e.g., or the values could simply be undocumented. – James McMahon Jul 12 '10 at 21:00
  • 18
    I think it says "e.g." because it's just a community documentation, if someone's interested in all the possible values, it can be found in Hibernate's javadoc. (And yes, only those four options are present) http://docs.jboss.org/hibernate/orm/4.1/javadocs/org/hibernate/cfg/AvailableSettings.html#HBM2DDL_AUTO – szegedi Sep 20 '12 at 13:21
  • 6
    validate says validate the schema , what exactly does it mean ?? – Hussain Akhtar Wahid 'Ghouri' Sep 18 '13 at 22:08
  • 1
    Hi - afaik I know, and saw throught usage, "validate" means just that - it will compare the database schema against your declared (or annotated) datalayer (Hibernate), and complain (or break?) if things do not match. But it won't make any changes to the database itself. – demaniak Oct 09 '13 at 15:41
  • 1
    A thing that i've had noticed is that if I change the column type into the model, the same column on database is not changed with **update** – Filipe May 21 '14 at 14:21
  • 'empty string' can also be used. – petertc Jun 06 '14 at 07:15
  • 9
    You can also use 'aardvark', or 'pigeon' or any other word, if you want hibernate to do nothing. Not that I would recommend that of course! – Ward Jun 16 '14 at 15:01
  • Is there any option that says, just create if don't exist, don't update, don't drop :( – mjs Dec 17 '14 at 17:01
  • 4
    A small addition to the create-drop option. If this option is used it does not drop the whole schema instead it drops the tables whose mappings are available while running this. For example if a database with Schema S has A, B, C tables and java code has mappings for A and B only then Hibernate will not drop the table C. – Aditya Feb 15 '15 at 17:09
  • @Aditya create-drop does not drop the "Schema" **and** does not create it. – Grim Mar 04 '16 at 10:53
  • Note that create-drop do not drop database just closing session but the **Session Factory**. – chAmi Jul 16 '16 at 13:04
  • My experience contradicts with @Ward's comment: when I use a value like "no_validation", I get: ``` java.lang.IllegalArgumentException: Unrecognized legacy `hibernate.hbm2ddl.auto` value : no_validation ``` – Shlomo Georg Konwisser Dec 31 '18 at 23:31
210

There's also the value of none to disable it entirely.

Marc Bannout
  • 388
  • 4
  • 15
Michiel Verkaik
  • 2,531
  • 1
  • 15
  • 3
  • 10
    This is actually quite useful since Hibernate’s schema validation sometimes fails for perfectly valid schemas. – Michael Piefel Jun 20 '12 at 08:51
  • 1
    I was just about to ask for something like this. My intention is to reduce startup time. – digao_mb Nov 07 '13 at 18:56
  • The 'none' value is very useful also when you want to use dynamic/programmatic configuration of Hibernate; any other value would cause an error when the application is started. – arpadf Apr 04 '14 at 16:57
  • 52
    **'empty string' is better than 'none'**. To use 'none', you will receive warning message: org.hibernate.cfg.SettingsFactory - Unrecognized value for "hibernate.hbm2ddl.auto": none – petertc Jun 06 '14 at 07:14
  • 18
    I've patched it. Added "none" as an explicitly valid constant. – Sanne May 03 '16 at 11:24
  • 11
    I like "hibernate.hbm2ddl.auto=potato" over others http://stackoverflow.com/a/15810379/838444 – Sneg Jul 20 '16 at 12:25
  • Look for log "Unrecognized hbm2ddl_auto value : none. Supported values include create, create-drop, update, and validate. Ignoring". :D – James Jithin Apr 20 '17 at 19:26
173

The configuration property is called hibernate.hbm2ddl.auto

In our development environment we set hibernate.hbm2ddl.auto=create-drop to drop and create a clean database each time we deploy, so that our database is in a known state.

In theory, you can set hibernate.hbm2ddl.auto=update to update your database with changes to your model, but I would not trust that on a production database. An earlier version of the documentation said that this was experimental, at least; I do not know the current status.

Therefore, for our production database, do not set hibernate.hbm2ddl.auto - the default is to make no database changes. Instead, we manually create an SQL DDL update script that applies changes from one version to the next.

Peter Hilton
  • 17,211
  • 6
  • 50
  • 75
  • 5
    Actually, per the documentation, create-drop creates the database tables and drops them when the session factory is explicitly closed. It does *not* drop the tables when the session factory is created. – Frans Jan 23 '14 at 09:30
  • 9
    No, both create-drop and create drop the tables when the sessionfactory is created, then create-drop drops the tables also when sessionfactory is closed. See http://stackoverflow.com/a/6752698/1536382 – Testo Testini Nov 03 '15 at 10:54
  • does making hibernate.hbm2ddl.auto=create-drop in production can lead to several connection timeout in production ? – METTAIBI Feb 09 '17 at 11:18
108

First, the possible values for the hbm2ddl configuration property are the following ones:

  • none - No action is performed. The schema will not be generated.
  • create-only - The database schema will be generated.
  • drop - The database schema will be dropped.
  • create - The database schema will be dropped and created afterward.
  • create-drop - The database schema will be dropped and created afterward. Upon closing the SessionFactory, the database schema will be dropped.
  • validate - The database schema will be validated using the entity mappings.
  • update - The database schema will be updated by comparing the existing database schema with the entity mappings.

The hibernate.hbm2ddl.auto="update" is convenient but less flexible if you plan on adding functions or executing some custom scripts.

So, The most flexible approach is to use Flyway.

However, even if you use Flyway, you can still generate the initial migration script using hbm2ddl.

Vlad Mihalcea
  • 142,745
  • 71
  • 566
  • 911
  • `drop` doesn't seem to be a valid option. Which version of hibernate are you referring to? – xagaffar Feb 04 '21 at 12:17
  • 1
    It's been a valid option since Hibernate 5.1, which was released in 2016. Check out the [`Action`](https://github.com/hibernate/hibernate-orm/blob/5eedda9a467fef44d924f64203023b2345b8415f/hibernate-core/src/main/java/org/hibernate/tool/schema/Action.java#L35) enum for more details. I assume you are using a very old Hibernate version. – Vlad Mihalcea Feb 04 '21 at 13:20
  • what is the exact difference between validate vs update. – Akash Verma May 22 '21 at 15:42
  • 1
    The answer tells the difference. – Vlad Mihalcea May 22 '21 at 16:46
52

I would use liquibase for updating your db. hibernate's schema update feature is really only o.k. for a developer while they are developing new features. In a production situation, the db upgrade needs to be handled more carefully.

Pat
  • 5,761
  • 5
  • 34
  • 50
  • 6
    See http://stackoverflow.com/questions/221379/hibernate-hbm2ddl-autoupdate-in-production for why you shouldn't use hbm2ddl for production. – Nathan Voxland Nov 04 '09 at 07:06
51

Although it is quite an old post but as i did some research on the topic so thought of sharing it.

hibernate.hbm2ddl.auto

As per the documentation it can have four valid values:

create | update | validate | create-drop

Following is the explanation of the behaviour shown by these value:

  • create :- create the schema, the data previously present (if there) in the schema is lost
  • update:- update the schema with the given values.
  • validate:- validate the schema. It makes no change in the DB.
  • create-drop:- create the schema with destroying the data previously present(if there). It also drop the database schema when the SessionFactory is closed.

Following are the important points worth noting:

  • In case of update, if schema is not present in the DB then the schema is created.
  • In case of validate, if schema does not exists in DB, it is not created. Instead, it will throw an error:- Table not found:<table name>
  • In case of create-drop, schema is not dropped on closing the session. It drops only on closing the SessionFactory.
  • In case if i give any value to this property(say abc, instead of above four values discussed above) or it is just left blank. It shows following behaviour:

    -If schema is not present in the DB:- It creates the schema

    -If schema is present in the DB:- update the schema.

amit
  • 807
  • 6
  • 14
27

hibernate.hbm2ddl.auto automatically validates and exports DDL to the schema when the sessionFactory is created.

By default, it does not perform any creation or modification automatically on DB. If the user sets one of the below values then it is doing DDL schema changes automatically.

  • create - doing creating a schema

    <entry key="hibernate.hbm2ddl.auto" value="create">
    
  • update - updating existing schema

    <entry key="hibernate.hbm2ddl.auto" value="update">
    
  • validate - validate existing schema

    <entry key="hibernate.hbm2ddl.auto" value="validate">
    
  • create-drop - create and drop the schema automatically when a session is starts and ends

    <entry key="hibernate.hbm2ddl.auto" value="create-drop">
    
Tom
  • 16,842
  • 17
  • 45
  • 54
Vinod Kumawat
  • 741
  • 5
  • 8
18

If you don't want to use Strings in your app and are looking for predefined constants have a look at org.hibernate.cfg.AvailableSettings class included in the Hibernate JAR, where you'll find a constant for all possible settings. In your case for example:

/**
 * Auto export/update schema using hbm2ddl tool. Valid values are <tt>update</tt>,
 * <tt>create</tt>, <tt>create-drop</tt> and <tt>validate</tt>.
 */
String HBM2DDL_AUTO = "hibernate.hbm2ddl.auto";
Stefan Haberl
  • 9,812
  • 7
  • 72
  • 81
10
  • validate: validates the schema, no change happens to the database.
  • update: updates the schema with current execute query.
  • create: creates new schema every time, and destroys previous data.
  • create-drop: drops the schema when the application is stopped or SessionFactory is closed explicitly.
Ravi K M
  • 77
  • 4
  • 16
vishal thakur
  • 609
  • 6
  • 7
7

I Think you should have to concentrate on the

SchemaExport Class 

this Class Makes Your Configuration Dynamic So it allows you to choose whatever suites you best...

Checkout [SchemaExport]

Vishal Sharma
  • 2,773
  • 2
  • 24
  • 36
4

validate: It validates the schema and makes no changes to the DB.
Assume you have added a new column in the mapping file and perform the insert operation, it will throw an Exception "missing the XYZ column" because the existing schema is different than the object you are going to insert. If you alter the table by adding that new column manually then perform the Insert operation then it will definitely insert all columns along with the new column to the Table. Means it doesn't make any changes/alters the existing schema/table.

update: it alters the existing table in the database when you perform operation. You can add or remove columns with this option of hbm2ddl. But if you are going to add a new column that is 'NOT NULL' then it will ignore adding that particular column to the DB. Because the Table must be empty if you want to add a 'NOT NULL' column to the existing table.

Arun Raaj
  • 1,762
  • 1
  • 21
  • 20
3

Since 5.0, you can now find those values in a dedicated Enum: org.hibernate.boot.SchemaAutoTooling (enhanced with value NONE since 5.2).

Or even better, since 5.1, you can also use the org.hibernate.tool.schema.Action Enum which combines JPA 2 and "legacy" Hibernate DDL actions.

But, you cannot yet configure a DataSource programmatically with this. It would be nicer to use this combined with org.hibernate.cfg.AvailableSettings#HBM2DDL_AUTO but the current code expect a String value (excerpt taken from SessionFactoryBuilderImpl):

this.schemaAutoTooling = SchemaAutoTooling.interpret( (String) configurationSettings.get( AvailableSettings.HBM2DDL_AUTO ) );

… and internal enum values of both org.hibernate.boot.SchemaAutoToolingand org.hibernate.tool.schema.Action aren't exposed publicly.

Hereunder, a sample programmatic DataSource configuration (used in ones of my Spring Boot applications) which use a gambit thanks to .name().toLowerCase() but it only works with values without dash (not create-drop for instance):

@Bean(name = ENTITY_MANAGER_NAME)
public LocalContainerEntityManagerFactoryBean internalEntityManagerFactory(
        EntityManagerFactoryBuilder builder,
        @Qualifier(DATA_SOURCE_NAME) DataSource internalDataSource) {

    Map<String, Object> properties = new HashMap<>();
    properties.put(AvailableSettings.HBM2DDL_AUTO, SchemaAutoTooling.CREATE.name().toLowerCase());
    properties.put(AvailableSettings.DIALECT, H2Dialect.class.getName());

    return builder
            .dataSource(internalDataSource)
            .packages(JpaModelsScanEntry.class, Jsr310JpaConverters.class)
            .persistenceUnit(PERSISTENCE_UNIT_NAME)
            .properties(properties)
            .build();
}
Doc Davluz
  • 4,154
  • 5
  • 30
  • 32
2

To whomever searching for default value...

It is written in the source code at version 2.0.5 of spring-boot and 1.1.0 at JpaProperties:

    /**
     * DDL mode. This is actually a shortcut for the "hibernate.hbm2ddl.auto"
     * property. Defaults to "create-drop" when using an embedded database and no
     * schema manager was detected. Otherwise, defaults to "none".
     */
    private String ddlAuto;
ibrahim demir
  • 421
  • 3
  • 16
0

With all above said... Notice this property is called dll.auto and should only control dll operations(create/drop schema/table), I found surprisingly that it has to do with dml, too: only update will allow insert data, which is dml operation.

Got caught by this when trying to populate data into a in-memory database; only update works.

WesternGun
  • 11,303
  • 6
  • 88
  • 157