hibernate Custom Naming Strategy Custom Physical Naming Strategy


When mapping our entities to database table names we rely on a @Table annotation. But if we have a naming convention for our database table names, we can implement a custom physical naming strategy in order to tell hibernate to calculate table names based on the names of the entities, without explicitly stating those names with @Table annotation. Same goes for attributes and columns mapping.

For example, our entity name is:


And our table name is:


Our Physical naming strategy needs to convert from entity names that are camel case to our db table names which are snake case. We can achieve this by extending hibernate's PhysicalNamingStrategyStandardImpl:

import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;

public class PhysicalNamingStrategyImpl extends PhysicalNamingStrategyStandardImpl {

    private static final long serialVersionUID = 1L;
    public static final PhysicalNamingStrategyImpl INSTANCE = new PhysicalNamingStrategyImpl();

    public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {
        return new Identifier(addUnderscores(name.getText()), name.isQuoted());

    public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment context) {
        return new Identifier(addUnderscores(name.getText()), name.isQuoted());

    protected static String addUnderscores(String name) {
        final StringBuilder buf = new StringBuilder(name);
        for (int i = 1; i < buf.length() - 1; i++) {
            if (Character.isLowerCase(buf.charAt(i - 1)) &&
                    Character.isUpperCase(buf.charAt(i)) &&
                    Character.isLowerCase(buf.charAt(i + 1))) {
                buf.insert(i++, '_');
        return buf.toString().toLowerCase(Locale.ROOT);

We are overriding default behavior of methods toPhysicalTableName and toPhysicalColumnName to apply our db naming convention.

In order to use our custom implementation we need to define hibernate.physical_naming_strategy property and give it the name of our PhysicalNamingStrategyImpl class.


This way we can alleviate our code from @Table and @Column annotations, so our entity class:

public class ApplicationEventLog {
    private Date startTimestamp;
    private String logUser;
    private Integer eventSuccess;

    private String finishDetails;

will be correctly be mapped to db table:

CREATE TABLE application_event_log (
  start_timestamp timestamp,
  log_user varchar(255),
  event_success int(11),
  finish_dtl varchar(2000),

As seen in the example above, we can still explicitly state the name of the db object if it is not, for some reason, in accordance with our general naming convention: @Column(name="finish_dtl")