Posted In: Hibernate

Hibernate 5 – hbm2ddl.auto explained

Note - hbm2ddl.auto is a facility to do faster development and testing. This should not be used in production.

hbm2ddl.auto has four options
1. validate
2. update
3. create4
4. create-drop
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.

Maven hibernate 5.2

<dependency>
	<groupId>org.hibernate</groupId>
	<artifactId>hibernate-tools</artifactId>
	<version>5.2.5.Final</version>
</dependency>
<dependency>
	<groupId>org.hibernate</groupId>
	<artifactId>hibernate-core</artifactId>
	<version>5.2.10.Final</version>
</dependency>
<dependency>
	<groupId>org.hibernate</groupId>
	<artifactId>hibernate-entitymanager</artifactId>
	<version>5.2.10.Final</version>
</dependency>
<dependency>
	<groupId>org.hibernate.javax.persistence</groupId>
	<artifactId>hibernate-jpa-2.1-api</artifactId>
	<version>1.0.0.Final</version>
</dependency>
<dependency>
	<groupId>javassist</groupId>
	<artifactId>javassist</artifactId>
	<version>3.12.1.GA</version>
</dependency>
<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<version>5.1.43</version>
</dependency>

 

hibernate.cfg.xml

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
 
<hibernate-configuration>
    <session-factory>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/new_schema</property>
        <property name="connection.username">root</property>
        <property name="connection.password">password</property>        
        <property name="connection.pool_size">1</property>
        <property name="dialect">org.hibernate.dialect.MySQL57Dialect</property>
        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
        <property name="show_sql">true</property>
        <property name="hbm2ddl.auto">create</property>
	<mapping class="com.example.hibernate.Employee"/>
    </session-factory>
</hibernate-configuration>

 

Create Hibernate SessionFactory


package com.example.hibernate;

import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {

	private static final SessionFactory sessionFactory = buildSessionFactory();

	private static SessionFactory buildSessionFactory() {

		try {
			Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
			configuration.addAnnotatedClass(Employee.class);
			StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder()
					.applySettings(configuration.getProperties());
			SessionFactory factory = configuration.buildSessionFactory(builder.build());

			return factory;
		} catch (Throwable ex) {
			ex.printStackTrace();
			throw new ExceptionInInitializerError(ex);
		}
	}

	public static SessionFactory getSessionFactory() {
		return sessionFactory;
	}
}

 

Create Hibernate POJO-Table mapping


GenerationType.IDENTITY - Will create AUTO_GENERATE primary key
length = 50 = Will create column with specified length

package com.example.hibernate;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "employee_master")
public class Employee {
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "EMPLOYEE_ID")
	private Long employeeId;
	@Column(name = "FIRST_NM", length = 50)
	private String firstName;
	@Column(name = "LAST_NM", length = 50)
	private String lastName;
......
//getter setter
}

 

Open session and save record


package com.example.hibernate;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

public class Main {

	public static void main(String[] args) {

		SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
		Session session = sessionFactory.openSession();
		try {
			Employee employee = new Employee();
			employee.setEmployeeId(0L);
			employee.setFirstName("Abhijit");
			employee.setLastName("Pednekar");
			session.beginTransaction();
			session.save(employee);

			session.getTransaction().commit();
		} catch (HibernateException e) {
			e.printStackTrace();
		} finally {
			session.close();
			sessionFactory.close();
		}
	}
}

 

Output hbm2ddl.auto=create


Hibernate: drop table if exists employee_master
Hibernate: create table employee_master (EMPLOYEE_ID bigint not 
null auto_increment, FIRST_NM varchar(50), LAST_NM varchar(50), 
primary key (EMPLOYEE_ID)) engine=InnoDB
Hibernate: insert into employee_master (FIRST_NM, LAST_NM) values (?, ?)

Output hbm2ddl.auto=create-drop. Hibernate will drop table at sessionFactory.close()


Hibernate: drop table if exists employee_master
Hibernate: create table employee_master (EMPLOYEE_ID bigint not null auto_increment, 
FIRST_NM varchar(50), LAST_NM varchar(50), primary key (EMPLOYEE_ID)) engine=InnoDB
Hibernate: insert into employee_master (FIRST_NM, LAST_NM) values (?, ?)
Hibernate: drop table if exists employee_master

Output hbm2ddl.auto=update. Hibernate will first create the table. Then change POJO and add a column


FIRST RUN
Hibernate: create table employee_master (EMPLOYEE_ID bigint not null auto_increment, 
FIRST_NM varchar(50), LAST_NM varchar(50), primary key (EMPLOYEE_ID)) engine=InnoDB
Hibernate: insert into employee_master (FIRST_NM, LAST_NM) values (?, ?)

SECOND RUN - Added new column 
@Column(name = "MIDLLE_NM", length = 50)
private String middleName;

Hibernate: alter table new_schema.employee_master add column MIDLLE_NM varchar(50)
Hibernate: insert into employee_master (FIRST_NM, LAST_NM, MIDLLE_NM) values (?, ?, ?)
 
 

Common errors

1. In case you follow Hibernate documentation then you may get this error.

Configuration().configure().buildSessionFactory(new StandardServiceRegistryBuilder().build());
Solution is to follow the example given above and use org.hibernate.cfg.Configuration


Caused by: org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set
	at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.determineDialect(DialectFactoryImpl.java:100)
	at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.buildDialect(DialectFactoryImpl.java:54)
	at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:137)
 
2. Caused due to driver not available in class path

Solution is to follow the example given above and use org.hibernate.cfg.Configuration


Caused by: java.lang.ClassNotFoundException: Could not load requested class : com.mysql.jdbc.Driver
at org.hibernate.boot.registry.classloading.internal.
ClassLoaderServiceImpl$AggregatedClassLoader.findClass(ClassLoaderServiceImpl.java:336)
 
3. Unknown database ‘new_schema’

Solution – create database


Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown database 'new_schema'
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
	at java.lang.reflect.Constructor.newInstance(Unknown Source)
	at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
	at com.mysql.jdbc.Util.getInstance(Util.java:408)
 
4. MappingException: Unknown entity

Solution – Use configuration.addAnnotatedClass(User.class) not configuration.addClass(User.class)


org.hibernate.MappingException: Unknown entity: com.example.hibernate.User
	at org.hibernate.metamodel.internal.MetamodelImpl.entityPersister(MetamodelImpl.java:620)
	at org.hibernate.internal.SessionImpl.getEntityPersister(SessionImpl.java:1634)
 
5. MySQLSyntaxErrorException: Table ‘new_schema.user’ doesn’t exist

Solution – Use org.hibernate.dialect.MySQL57Dialect not org.hibernate.dialect.MySQLDialect


Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table 'new_schema.user' doesn't exist
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
 
6. AnnotationException: No identifier specified for entity

Solution – Add javax.persistence.Id to POJO


org.hibernate.AnnotationException: No identifier specified for entity
 
7. java.lang.NoSuchMethodError

Solution – Check maven entries


java.lang.NoSuchMethodError: org.hibernate.jpa.internal.util.ConfigurationHelper.getFlushMode

by , on September 3rd, 2017

  • Categories