4

We're currently trying to move our web app from Wildfly 9.0.2 to Wildfly 10.1.0, and so migrating from Hibernate 4.3.10 to 5.0.10.

We never defined our own NamingStrategy, using whatever names Hibernate chooses for our Entities (our Postgresql database is built through hbm2ddl).

Now, with Hibernate 5, we have unknown column errors as the naming convention seems to have changed. Specifically, in join tables, column names are now based on true class instead of parent: for example, where we have a UserEntity which inherits from AgentEntity, before we got a agentEntity_id column, now it's a userEntity_id column.

I try the four existing Hibernate ImplicitNamingStrategies (jpa, legacy-jpa, legacy-hbm and component-path) in our persistence.xml, without success: each one differs from the old strategy.

So, is there a way to avoid rewriting my own strategy to keep compliance with our old model?

Xavier Portebois
  • 3,354
  • 6
  • 33
  • 53

1 Answers1

1

I had this same problem migrating to Hibernate 5, though we have an Oracle backend. I was able to achieve a similar naming strategy to what I had out of the box with Hibernate 4 by utilizing both org.hibernate.boot.model.naming.ImplicitNamingStrategy and org.hibernate.boot.model.naming.PhysicalNamingStrategy.

Here is what my bean definition looks like from my application context:

@Bean
@Primary
public static JpaProperties jpaProperties() {
  final Map<String, String> hibernateConfig = newHashMap();
  hibernateConfig.put("hibernate.implicit_naming_strategy",      
  "org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl");
  hibernateConfig.put("hibernate.physical_naming_strategy",
  "com.anyapp.CustomNamingStrategy");

  final JpaProperties jpaProperties = new JpaProperties();
  jpaProperties.setProperties(hibernateConfig);
  jpaProperties.setDatabase(ORACLE);
  jpaProperties.setDatabasePlatform(ORACLE12C_DIALECT);
  jpaProperties.setGenerateDdl(false);
  jpaProperties.setShowSql(false);
  return jpaProperties;
}

The most annoying part was to find out which naming strategies to apply in what way and the fact that I had to implement CustomNamingStrategy on my own, as Hibernate does not provide a PhysicalNamingStrategy that matches the naming of legacy ImprovedNamingStrategy.

Here are the contents of my CustomNamingStrategy:

package com.anyapp;

import org.apache.commons.lang.StringUtils;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;

public class CustomNamingStrategy implements PhysicalNamingStrategy {

    @Override
    public Identifier toPhysicalCatalogName(Identifier identifier, JdbcEnvironment jdbcEnv) {
        return convert(identifier);
    }

    @Override
    public Identifier toPhysicalColumnName(Identifier identifier, JdbcEnvironment jdbcEnv) {
        return convert(identifier);
    }

    @Override
    public Identifier toPhysicalSchemaName(Identifier identifier, JdbcEnvironment jdbcEnv) {
        return convert(identifier);
    }

    @Override
    public Identifier toPhysicalSequenceName(Identifier identifier, JdbcEnvironment jdbcEnv) {
        return convert(identifier);
    }

    @Override
    public Identifier toPhysicalTableName(Identifier identifier, JdbcEnvironment jdbcEnv) {
        return convert(identifier);
    }

    private Identifier convert(Identifier identifier) {
        if (identifier == null || StringUtils.isBlank(identifier.getText())) {
            return identifier;
        }

        String regex = "([a-z])([A-Z])";
        String replacement = "$1_$2";
        String newName = identifier.getText().replaceAll(regex, replacement).toLowerCase();
        return Identifier.toIdentifier(newName);
    }
}

You may have to adjust the regex to fit your exact needs, but this is what worked for me.

lax1089
  • 3,403
  • 3
  • 17
  • 37
  • I agreed, it seems to me too that Hibernate doesn't have a physical naming strategy compliant with their legacy one. Could you care to share your com.anyapp.CustomNamingStrategy? – Xavier Portebois Apr 25 '17 at 07:13
  • 1
    I have added the contents of my CustomNamingStrategy implementation to my answer – lax1089 Apr 25 '17 at 11:14