43

I have database fields in underscore. I have entity fields in camelcase. I can't change either of those.

Is there something, maybe a class level annotation I can use to default entity column name annotations to the camelcase equivalent?

for example, I have an entity like this:

@Entity
public class AuthorisationEntity {

    @Column(name = "non_recoverable")
    private BigDecimal nonRecoverable;

    @Column(name = "supplier_recoverable")
    private BigDecimal supplierRecoverable;

    @Column(name = "refund_amount")
    private BigDecimal refundAmount;

}

I dream of this:

@Entity
@DatabaseIsUnderscoreAndThisAnnotationConvertsThemToCamelCaseByDefault
public class AuthorisationEntity {

    private BigDecimal nonRecoverable;

    private BigDecimal supplierRecoverable;

    private BigDecimal refundAmount;

}
1
  • 6
    I can't find the class @DatabaseIsUnderscoreAndThisAnnotationConvertsThemToCamelCaseByDefault ... Just kidding, but I really wanted to paste this to my friend. :) Commented Nov 7, 2016 at 23:37

5 Answers 5

21

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?

Sign up to request clarification or add additional context in comments.

5 Comments

Two shots of whiskey to this gentleman! This finally fixes snake case naming strategy for hibernate 5!
This is not working. Do you have any idea what it could be? javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not extract ResultSet. I am using the implementation("com.vladmihalcea", "hibernate-types-52","2.10.0") and I put the property in the hibernate.cfg
You can find plenty of test cases on GitHub that prove it works. Compare my tests to yours to see where they differ
hibernate-types is awesome! I'm using it for Postgres extensions support.
I'm glad you liked it.
16

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

1 Comment

This looks like it will do what I need, nice one
5

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;
    }

Comments

4

From Hibernate 5.5.4.Final, CamelCaseToUnderscoresNamingStrategy has been introduced, the new strategy is the equivalent of the Spring SpringPhysicalNamingStrategy.

The CamelCaseToUnderscoresNamingStrategy replaces all dots with underscores, all camel casing with underscores and generates all table names in lower case.

For example, the LineItem entity will be mapped to the line_item table.

Comments

1
import org.hibernate.cfg.DefaultNamingStrategy;
import org.hibernate.cfg.ImprovedNamingStrategy;

public class NamingStratagyTest {
    public static void main(String[] args) {
        String colName = DefaultNamingStrategy.INSTANCE.columnName("UserName");
        System.out.println(colName); // UserName
        colName = ImprovedNamingStrategy.INSTANCE.columnName("UserName");
        System.out.println(colName);// user_name
    }
}

There you go, choose the naming strategy that suits your need.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.