Last Updated on 23 May 2020   |   Print Email
When using Hibernate framework, we usually create entity classes to map with tables in the database. This process is called reverse engineering, which is suitable if the database does exist before the coding. Otherwise, we should use Hibernate forward engineering which creates entity classes first and then let Hibernate automatically create tables in the database – so we can save time and avoid mistakes if create tables manually.To use Hibernate forward engineering, you need to specify the hibernate.hbm2ddl.auto property in Hibernate configuration file. For example:
In case you’re using Spring Boot with Spring Data JPA and Hibernate, add the following entry in the application.properties file:
spring.jpa.hibernate.ddl-auto=create
Now, let’s understand some possible values for this property.
1. Possible values of the property hibernate.hbm2ddl.auto
You can specify one of the following values for the hibernate.hbm2ddl.auto property:
create: let Hibernate creates tables according to the mapped entity classes. Hibernate attempts to drop the tables if exist. So use this value when you want to create the database for the first time. If you use it in the 2nd time, previous data will be lost.
create-drop: use this value if you want Hibernate to create tables and then drop them when the session ends. This value is suitable for running unit tests on a temporary database or in-memory database, without the need to keep data.
update: use this value in case you want to apply changes in the entity classes into the database, e.g. adding new columns to an existing table, or create additional tables from new entity classes. Note that Hibernate won’t alter the tables if you change only attributes of columns, e.g. nullability, unique, length, and the like.
validate: use this value if you want Hibernate to validate the database schema against the mapped entity classes. Upon testing, I found that Hibernate checks only if the tables exist or not. If not, it throws SchemaManagementException – reporting tables missing.
none: tell Hibernate do not touch the database schema. Use this value when the database is stable and in production mode.
2. Specify exact database dialect
Hibernate uses the SQL syntax of the target database to create tables accordingly, so it’s important to specify database dialect information exactly matches the type of the underlying database. Otherwise, you will get error or undesired behaviors.For example, for MySQL database:
Check this document to see the list of database dialect supported by Hibernate framework.
3. Hibernate Forward Engineering Example
Now, let me walk you through the development process of a Java project to demonstrate Hibernate forward engineering.Create an entity class Productwith the following code:
As you can see, we use JPA annotations to map this entity class with a database table (not exists before). If the table name/field name name is as same as the table name/column name, then you don’t have to specify the name attribute.Then create the Hibernate configuration file hibernate.cfg.xml as follows:
Here, we specify create for the hibernate.hbm2ddl.auto property so Hibernate will create a table from the entity class. Note that you should create a database schema named testdb in the database.Next, code a simple test program as follows:
package net.codejava;
import org.hibernate.*;
import org.hibernate.boot.*;
import org.hibernate.boot.registry.*;
public class HibernateForwardEngineeringTest {
public static void main(String[] args) {
final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
.configure() // configures settings from hibernate.cfg.xml
.build();
try {
SessionFactory factory = new MetadataSources(registry)
.buildMetadata().buildSessionFactory();
Session session = factory.openSession();
Transaction transaction = session.beginTransaction();
Product product = new Product();
product.setName("iPhone 7 Plus");
product.setDescription("A good smartphone");
product.setPrice(1299.89f);
product.setEnabled(true);
session.save(product);
transaction.commit();
session.close();
factory.close();
} catch (Exception ex) {
System.out.println(ex.getMessage());
ex.printStackTrace();
StandardServiceRegistryBuilder.destroy(registry);
}
}
}
This program simply persists a Product object to a session, which results in inserting a new row into the database table. Run this program and you would see Hibernate prints the following SQL statements:
drop table if exists products
create table products (
product_id integer not null auto_increment,
description varchar(512),
enabled tinyint default 1,
name varchar(128),
price float,
primary key (product_id)
) engine=InnoDB
insert
into
products
(description, enabled, name, price)
values
(?, ?, ?, ?)
Check the database (use MySQL Workbench) to verity the table actually created with one row inserted. Then play with other values of the hibernate.hbm2ddl.auto property: create-drop, update, validate and none. ConclusionHibernate forward engineering is a convenient feature that helps programmer save time and avoid mistakes with regarding to database schema creation. You can use different value of the hibernate.hbm2ddl.auto property in different phases of the development process to get the most out of it.Watch the video version:
Nam Ha Minh is certified Java programmer (SCJP and SCWCD). He began programming with Java back in the days of Java 1.4 and has been passionate about it ever since. You can connect with him on Facebook and watch his Java videos on YouTube.
Comments