Last Updated: February 25, 2016
·
4.391K
· steviebraga

Hibernate Custom Naming Strategy

By a client demand, I needed to change the way Hibernate names the foreign key columns.

By default, Hibernate adds the referenced column as a suffix, for example, entity_id, but I needed to add the referenced column as a prefix so it'd be named as id_entity.

Instead of annotating all the fields with the @Column and use the name property, I decided to customize the way Hibernate names these columns. To do this I need to create a custom Naming Strategy.

In Hibernate 4.3.5. you need to create a org.hibernate.cfg.naming.NamingStrategyDelegator and a org.hibernate.cfg.naming.NamingStrategyDelegateAdapter and declare it in the persistence.xml file.

So here is how I solved it:

import java.io.Serializable;

import org.hibernate.cfg.naming.HbmNamingStrategyDelegate;
import org.hibernate.cfg.naming.NamingStrategyDelegate;
import org.hibernate.cfg.naming.NamingStrategyDelegator;

public class CustomNamingStrategyDelegator implements NamingStrategyDelegator, Serializable {

    private static final long serialVersionUID = -1880672539574785139L;

    public static final NamingStrategyDelegator DEFAULT_INSTANCE = new CustomNamingStrategyDelegator();

    private final NamingStrategyDelegate hbmNamingStrategyDelegate;
    private final NamingStrategyDelegate jpaNamingStrategyDelegate;

    public CustomNamingStrategyDelegator() {
        this( new HbmNamingStrategyDelegate(), new CustomJpaNamingStrategyDelegate() );
    }

    protected CustomNamingStrategyDelegator( NamingStrategyDelegate hbmNamingStrategyDelegate, NamingStrategyDelegate jpaNamingStrategyDelegate ) {
        this.hbmNamingStrategyDelegate = hbmNamingStrategyDelegate;
        this.jpaNamingStrategyDelegate = jpaNamingStrategyDelegate;
    }

    @Override
    public NamingStrategyDelegate getNamingStrategyDelegate( boolean isHbm ) {
        return isHbm ? hbmNamingStrategyDelegate : jpaNamingStrategyDelegate;
    }

}
import org.hibernate.AssertionFailure;
import org.hibernate.cfg.naming.JpaNamingStrategyDelegate;
import org.hibernate.internal.util.StringHelper;

public class CustomJpaNamingStrategyDelegate extends JpaNamingStrategyDelegate {

    private static final long serialVersionUID = 1294347082667342357L;

    @Override
    public String determineImplicitEntityAssociationJoinColumnName( String propertyEntityName, String propertyJpaEntityName, String propertyTableName, String referencedColumnName, String referencingPropertyName ) {

        final String header;
        if ( referencingPropertyName == null ) {
            header = determineEntityNameToUse( propertyEntityName, propertyJpaEntityName );
        } else {
            header = StringHelper.unqualify( referencingPropertyName );
        }
        if ( header == null ) {
            throw new AssertionFailure( "propertyJpaEntityName and referencingPropertyName cannot both be empty." );
        }
        return toPhysicalColumnName( referencedColumnName + "_" + header );
    }

    private String determineEntityNameToUse( String entityName, String jpaEntityName ) {
        if ( StringHelper.isNotEmpty( jpaEntityName ) ) {
            return jpaEntityName;
        } else {
            return StringHelper.unqualifyEntityName( entityName );
        }
    }

}

Then declare it in persistence.xml

<properties>
            ...

            <property name="hibernate.ejb.naming_strategy_delegator" value="package.CustomNamingStrategyDelegator"/>

            ...
</properties>