How to map Hibernate entity fields using camelCase to snake_case (underscore) database identifiers
You can use hibernate's naming strategy. Such naming strategy class describes how to generate database names for given java names.
See:
naming strategy example
second example
very good oracle naming strategy - it converts camel to underscore convention, and much more
You can achieve this using a custom Hibernate naming strategy.
All you need to do is to use the hibernate-types
open-source project.
Hibernate 5.2 or later
You need to add the following Maven dependency:
<dependency>
<groupId>com.vladmihalcea</groupId>
<artifactId>hibernate-types-52</artifactId>
<version>${hibernate-types.version}</version>
</dependency>
And set the following Hibernate configuration property:
<property name="hibernate.physical_naming_strategy"
value="com.vladmihalcea.hibernate.type.util.CamelCaseToSnakeCaseNamingStrategy"
/>
Hibernate 5.0 and 5.1
You need to add the following Maven dependency:
<dependency>
<groupId>com.vladmihalcea</groupId>
<artifactId>hibernate-types-5</artifactId>
<version>${hibernate-types.version}</version>
</dependency>
And set the following Hibernate configuration property:
<property name="hibernate.physical_naming_strategy"
value="com.vladmihalcea.hibernate.type.util.CamelCaseToSnakeCaseNamingStrategy"
/>
Hibernate 4.3
You need to add the following Maven dependency:
<dependency>
<groupId>com.vladmihalcea</groupId>
<artifactId>hibernate-types-43</artifactId>
<version>${hibernate-types.version}</version>
</dependency>
And set the following Hibernate configuration property:
<property name="hibernate.ejb.naming_strategy"
value="com.vladmihalcea.hibernate.type.util.CamelCaseToSnakeCaseNamingStrategy"
/>
Hibernate 4.2 and 4.1
You need to add the following Maven dependency:
<dependency>
<groupId>com.vladmihalcea</groupId>
<artifactId>hibernate-types-4</artifactId>
<version>${hibernate-types.version}</version>
</dependency>
And set the following Hibernate configuration property:
<property name="hibernate.ejb.naming_strategy"
value="com.vladmihalcea.hibernate.type.util.CamelCaseToSnakeCaseNamingStrategy"
/>
Testing time
Assuming you have the following entities:
@Entity(name = "BookAuthor")
public class BookAuthor {
@Id
private Long id;
private String firstName;
private String lastName;
//Getters and setters omitted for brevity
}
@Entity(name = "PaperBackBook")
public class PaperBackBook {
@Id
@GeneratedValue(
strategy = GenerationType.SEQUENCE
)
private Long id;
@NaturalId
private String ISBN;
private String title;
private LocalDate publishedOn;
@ManyToOne(fetch = FetchType.LAZY)
private BookAuthor publishedBy;
//Getters and setters omitted for brevity
}
When using the CamelCaseToSnakeCaseNamingStrategy
custom naming strategy, Hibernate is going to generate the following database schema using the hbm2ddl
tool:
CREATE SEQUENCE hibernate_sequence
START WITH 1 INCREMENT BY 1
CREATE TABLE book_author (
id BIGINT NOT NULL,
first_name VARCHAR(255),
last_name VARCHAR(255),
PRIMARY KEY (id)
)
CREATE TABLE paper_back_book (
id BIGINT NOT NULL,
isbn VARCHAR(255),
published_on DATE,
title VARCHAR(255),
published_by_id BIGINT,
PRIMARY KEY (id)
)
Cool, right?
I was experiencing the same problem in a Spring boot application, I tried adding the above Hibernate config to the spring properties file with no success, added it as a java bean, again with no success.
I am using Hibernate Properties
object, adding the hibernate configuration within this solved my issue:
protected Properties buildHibernateProperties() {
Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.implicit_naming_strategy", SpringImplicitNamingStrategy.class.getName());
hibernateProperties.setProperty("hibernate.physical_naming_strategy", SpringPhysicalNamingStrategy.class.getName());
return hibernateProperties;
}