Is it possible to dynamically define column names in Hibernate / JPA?

You need to create a custom NamingStrategy.

Assuming you use spring and hibernate with JPA, here is a configuration snippet with a custom NamingStrategy:

<bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="myunit" />
    <property name="dataSource" ref="dataSource" />
    <property name="persistenceXmlLocation"
              value="classpath:META-INF/persistence.xml" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="showSql" value="false" />
            <property name="generateDdl" value="true" />
            <property name="database" value="MYSQL" />
        </bean>
    </property>
    <property name="jpaProperties">
        <props>
            <prop 
                key="hibernate.ejb.naming_strategy">
                com.yourcompany.CustomNamingStrategy
            </prop>
        </props>
    </property>
</bean>

If you don’t use spring, configuration will be different, but you can still use a custom NamingStrategy (see Implementing a NamingStrategy from the Hibernate Documentation).

Anyway, here is a sample NamingStrategy that builds table names of the form TYPE1_TYPE2 for join tables and adds a common prefix to all tables:

public class CustomNamingStrategy extends ImprovedNamingStrategy {

    private static final long serialVersionUID = 1L;
    private static final String PREFIX = "PFX_";

    @Override
    public String classToTableName(final String className) {
        return this.addPrefix(super.classToTableName(className));
    }

    @Override
    public String collectionTableName(final String ownerEntity,
            final String ownerEntityTable, final String associatedEntity,
            final String associatedEntityTable, final String propertyName) {
        return this.addPrefix(super.collectionTableName(ownerEntity,
                ownerEntityTable, associatedEntity, associatedEntityTable,
                propertyName));
    }

    @Override
    public String logicalCollectionTableName(final String tableName,
            final String ownerEntityTable, final String associatedEntityTable,
            final String propertyName) {
        return this.addPrefix(super.logicalCollectionTableName(tableName,
                ownerEntityTable, associatedEntityTable, propertyName));
    }

    private String addPrefix(final String composedTableName) {

        return PREFIX
                + composedTableName.toUpperCase().replace("_", "");

    }

}

Leave a Comment