Hi, Habr! I present to your attention 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. And at the end we will explore the implementation of the custom naming strategy and configuration for run using spring boot.
Hibernate 4 naming strategy
Hibernate uses this strategy to match the java entity and attribute with the corresponding relational database and column names. In hibernate 4, the hibernate.ejb.naming_strategy naming strategy was used. This strategy uses EJB3NamingStrategy, ImprovedNamingStrategy, DefaultComponentSafeNamingStrategy and DefaultNamingStrategy for name matching. EJB3NamingStrategy is the default naming strategy, and it provides camelCase-style field and table names. While the naming of a foreign key column uses an underscore (_) as a division. 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, since the NamingStrategy contract is often not flexible enough to correctly apply this “naming” rule. Instead, two new strategies were introduced that provide deep customization of the naming strategy, called ImplicitNamingStrategy and PhysicalNamingStrategy. To use these strategies, there are two keys that implicit_naming_strategy and physical_naming_strategy will use. Hibernate 5 provides only one implementation of the PhysicalNamingStrategy - PhysicalNamingStrategyStandardImpl, but several implementations of ImplicitNamingStrategy.
')
ImplicitNamingStrategy is used when you do not specify the name of the database and column explicitly in the definition of an entity, because PhysicalNamingStrategy can be used to explicitly define the rules of matching an entity and an attribute name with the name of a database and columns.
ImplicitNamingStrategy
ImplicitNamingStrategy is used when an object does not explicitly indicate the database table to which it is associated, or when a particular attribute does not explicitly indicate the column of the database with which it is associated. We can specify which ImplicitNamingStrategy to use using the configuration hibernate.implicit_naming_strategy, which accepts default, jpa, legacy-hbm, legacy-jpa and component-path.
PhysicalNamingStrategy
The idea of ​​PhysicalNamingStrategy is to define custom naming rules without having to hardcoding them using 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 hibernate strategy, run the following configuration:
jpaProperties.put("hibernate.physical_naming_strategy", "com.devglan.config.CustomPhysicalNamingStrategy");
Hibernate naming strategy in Spring Boot
As we said, hibernate provides two different naming strategies, while Spring Boot sets up a physical naming strategy using the SpringPhysicalNamingStrategy, where all points are replaced with underscores, and camelCase is replaced with underscores, and all table names are generated in lower case. For example, a USERDETAILS object is mapped to a 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 add to the article or share, feel free to do it in the comments section.
