Various naming strategies in Hibernate

Hello, Habr! I present to you the translation of the article " Different Hibernate Naming Strategy " by Dhiraj Ray.

This article discusses the various naming strategies provided by hibernate, as well as the transition of the naming strategy from hibernate.ejb.naming_strategy in hibernate 4 to hibernate.implicit_naming_strategy and hibernate.physical_naming_strategy in hibernate 5. In the end, we will examine the implementation of the custom naming strategy and configuration launch using spring boot.

Hibernate 4 Naming Strategy


Hibernate uses this strategy to map the java entity and attribute to the corresponding relational database and column name. Hibernate 4 used the naming strategy hibernate.ejb.naming_strategy. This strategy uses EJB3NamingStrategy, ImprovedNamingStrategy, DefaultComponentSafeNamingStrategy and DefaultNamingStrategy to match names. EJB3NamingStrategy is the default naming strategy, and it provides camelCase-style field and table names. While naming a foreign key column uses the underscore (_) as a separation. For example, if you have a table with the name and table1 with the column names id and name, then in the second table the foreign key column will be created as table1_id, so EJB3NamingStrategy implements the NamingStrategy interface.

Hibernate 5 Naming Strategy


After the release of Hibernate 5, hibernate.ejb.naming_strategy is no longer used, because the NamingStrategy contract is often not flexible enough to correctly apply this naming rule. Instead, two new strategies have been introduced that deeply customize the naming strategies called ImplicitNamingStrategy and PhysicalNamingStrategy. To use these strategies, there are two keys that will be used by implicit_naming_strategy and physical_naming_strategy. Hibernate 5 provides only one PhysicalNamingStrategy implementation - PhysicalNamingStrategyStandardImpl, but several ImplicitNamingStrategy implementations.

ImplicitNamingStrategy is used when you do not explicitly specify the name of the database and column in the entity definition, since PhysicalNamingStrategy can be used to explicitly define the rules for matching the entity and the attribute name with the name of the database and columns.

ImplicitNamingStrategy


ImplicitNamingStrategy is used when the object does not explicitly indicate the database table to which it is bound, or when a particular attribute does not explicitly indicate the database column with which it is mapped. We can specify which ImplicitNamingStrategy to use with the hibernate.implicit_naming_strategy configuration, which accepts default, jpa, legacy-hbm, legacy-jpa and component-path.

PhysicalNamingStrategy


The idea behind PhysicalNamingStrategy is to define custom naming rules without the need for hardcoding to match through explicit names. The following is an implementation of PhysicalNamingStrategy to determine the 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 use this custom strategy in hibernate, complete the following configuration:

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

Hibernate Naming Strategy in Spring Boot


As we already said, hibernate provides two different naming strategies, while Spring Boot sets up a physical naming strategy using SpringPhysicalNamingStrategy, where all dots are replaced by underscores, and camelCase is replaced by underscores, and all table names are lowercase. For example, the USERDETAILS object maps to the user_details table.

If you want to use your own naming strategy implemented above, you can do the following configuration in application.properties.

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

Conclusion


In this article, you learned about the various naming strategies provided by Spring Boot and Hibernate, as well as how to implement our own naming strategy. If you have something that you would like to supplement the article or share, feel free to do it in the comments section.


Also popular now: