Stan Stan - 1 year ago 197
Java Question

Need help in implementing ImplicitNamingStrategy for foreign key column names in Hibernate 5

I am trying to add underscores for the foreign key column names by overriding the method determineForeignKeyName in ImplicitNamingStrategyJpaCompliantImpl class, but somehow its not working. Below is the class i created,

public class CustomNamingStrategy extends ImplicitNamingStrategyJpaCompliantImpl implements Serializable{

public static final CustomNamingStrategy INSTANCE=new CustomNamingStrategy ();

* Produces a plural table name from the given class name
* @return a pluralized version of the class name using underscores instead of mixed case.
protected String transformEntityName(EntityNaming entityNaming) {
return Noun.pluralOf(addUnderscores(StringHelper.unqualify(entityNaming.getEntityName())));

protected static String addUnderscores(String name) {
StringBuilder buf = new StringBuilder(name.replace('.', '_'));
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);

public Identifier determineForeignKeyName(ImplicitForeignKeyNameSource source) {

return toIdentifier(

public List<Identifier> addUnderscorestocolumns(List<Identifier> columnNamesList) {

List<Identifier> underscorecolumns = new ArrayList<Identifier>();

for (int i = 0; i < columnNamesList.size(); i++) {
underscorecolumns.add(Identifier.toIdentifier(addUnderscores(columnNamesList.get(i).getText()))) ;
return underscorecolumns;

public Identifier determineBasicColumnName(ImplicitBasicColumnNameSource source) {

return toIdentifier(transformAttributePathCustom(source.getAttributePath()), source.getBuildingContext());

protected String transformAttributePathCustom(AttributePath attributePath) {
return addUnderscores(attributePath.getProperty());


So, except the determineForeignKeyName method, others methods are working as expected, like adding plural names and underscore for the tables. When i debug through the code, i can see the control going into the determineForeignKeyName method for the foreign key columns and underscores are added, but when the control goes to InflightMetadataCollectorImpl class (org.hibernate.boot.internal), i can see only referenced column is added, but not the underscores for the column name.

Is there any other method i need to implement for foreign key column names or i there any error in my implementation? Please suggest.

Answer Source

NamingHelper.INSTANCE.generateHashedFkName() generates a hashed name. You need something like this

public Identifier determineForeignKeyName(ImplicitForeignKeyNameSource source) {
    return toIdentifier(
                "FK_" +
                source.getTableName().getText() + "_" +
                source.getReferencedTableName().getText() + "_" +

You can refer as an example Hibernate5NamingStrategy

The method Identifier determineForeignKeyName(ImplicitForeignKeyNameSource source) is not used for generate column names, but foreign key constraint names like F_users_fk_address for this SQL

alter table users 
  add constraint F_users_fk_address 
  foreign key (fk_address) 
  references user_addresses (f_pid)

To specify foreign key column names you need to override this method

Identifier determineJoinColumnName(ImplicitJoinColumnNameSource source)

Refer this: