Different Hibernate Naming Strategy

By Dhiraj Ray, 20 January,2018   1K

This article discusses about different naming strategy provided by hibernate along with the shift of naming strategy from hibernate.ejb.naming_strategy in hibernate 4 to hibernate.implicit_naming_strategy and hibernate.physical_naming_strategy in hibernate 5.And at the end, we wil be take a look into implementing a custom naming strategy in hibernate and configuration to run with spring boot application.

Hibernate 4 Naming Strategy

Hibernate uses these strategy to map the java entity and attribute name with corresponding relational database and columns name. In hibernate 4, the naming strategy used was hibernate.ejb.naming_strategy. This strategy uses EJB3NamingStrategy , ImprovedNamingStrategy, DefaultComponentSafeNamingStrategy and DefaultNamingStrategy to map the names. EJB3NamingStrategy is the default naming strategy used and it provides camelcase field and table names.While naming foreign key column it uses undescore(_) as a seperation. For example if you have a table with name and table1 with column names as id and name, then in table2 the foreign key column will be created as table1_id and this EJB3NamingStrategy implements NamingStrategy interface.

Hibernate 5 Naming Strategy

After the release of Hibernate 5, hibernate.ejb.naming_strategy is no longer avilable as NamingStrategy contract was often not flexible enough to properly apply a given naming "rule". Instead two new strategy was introduced to provide deep customization of the naming strategy and they are ImplicitNamingStrategy and PhysicalNamingStrategy. To use this strategy there are two keys to be used implicit_naming_strategy and physical_naming_strategy.Hibernate 5 provides only one implementation of PhysicalNamingStrategy - PhysicalNamingStrategyStandardImpl but several implementations of ImplicitNamingStrategy.

ImplicitNamingStrategy is used when you don't provide the database and column name explicitly in the entity definition where as PhysicalNamingStrategy can be used to explicitly define mapping rules of the entity and attribute name with the database and columns name.

ImplicitNamingStrategy

ImplicitNamingStrategy is used when an entity does not explicitly name the database table that it maps to or when a particular attribute does not explicitly name the database column that it maps to.We can specify which ImplicitNamingStrategy to use using the hibernate.implicit_naming_strategy configuration setting which accepts default, jpa, legacy-hbm, legacy-jpa and component-path.

PhysicalNamingStrategy

The idea of a PhysicalNamingStrategy is to define custom naming rules without having to hard-code them into the mapping via explicit names.Following is an implementation of PhysicalNamingStrategy to define custom table name and column name.

package com.devglan;

import java.util.LinkedList;
import java.util.List;
import java.util.Locale;

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

import org.apache.commons.lang3.StringUtils;

public class CustomPhysicalNamingStrategy implements PhysicalNamingStrategy {

    @Override
    public Identifier toPhysicalCatalogName(Identifier name, JdbcEnvironment jdbcEnvironment) {
        return name;
    }

    @Override
    public Identifier toPhysicalSchemaName(Identifier name, JdbcEnvironment jdbcEnvironment) {
        return name;
    }

    @Override
    public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment jdbcEnvironment) {
        final List parts = splitAndReplace( name.getText() );
        return jdbcEnvironment.getIdentifierHelper().toIdentifier(
                join( parts ),
                name.isQuoted()
        );
    }

    @Override
    public Identifier toPhysicalSequenceName(Identifier name, JdbcEnvironment jdbcEnvironment) {
        return name;
    }

    @Override
    public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment jdbcEnvironment) {
        final List parts = splitAndReplace( name.getText() );
        return jdbcEnvironment.getIdentifierHelper().toIdentifier(
                join( parts ),
                name.isQuoted()
        );
    }

    private LinkedList splitAndReplace(String name) {
        LinkedList result = new LinkedList<>();
        for ( String part : StringUtils.splitByCharacterTypeCamelCase( name ) ) {
            if ( part == null || part.trim().isEmpty() ) {
                continue;
            }
            result.add( part.toUpperCase( Locale.ROOT ) );
        }
        return result;
    }

    private String join(List parts) {
        boolean firstPass = true;
        String separator = "";
        StringBuilder joined = new StringBuilder();
        for ( String part : parts ) {
            joined.append( separator ).append( part );
            if ( firstPass ) {
                firstPass = false;
                separator = "_";
            }
        }
        return joined.toString();
    }
}

To make use of this custom strategy in hibernate, following is the configuration.

jpaProperties.put("hibernate.physical_naming_strategy", "com.devglan.config.CustomPhysicalNamingStrategy");

Hibernate Naming Strategy in Spring Boot

As we discussed, hibernate provides two different naming strategy whereas Spring Boot configures the physical naming strategy with SpringPhysicalNamingStrategy where all dots are replaced by underscores and camel casing is replaced by underscores and all table names are generated in lower case.For example, a USERDETAILS entity is mapped to the user_details table.

If you want to use your own custom naming strategy as implemented above, you can make following configuration in application.properties.

spring.jpa.hibernate.naming.physical-strategy=com.devglan.config.CustomPhysicalNamingStrategy);

Conclusion

In this article we learned about different naming strategy provided by spring boot and hibernate and ways to implement our own custom naming strategy. If you have anything that you want to add or share then please share it below in the comment section.

Further Reading on Hibernate

1. Spring Boot Hibernate 5 Example

2. Spring Data Jpa Example

3. Object Relational Mapping In Java

4. Hibernate One To One Mapping Example

5. Spring Boot Mvc App With Jsp

If You Appreciate What We Do Here On Devglan, You Should Consider:

References

Spring Boot Naming Strategy

Spring Boot Naming Strategy

Stackoverflow link