4

我们目前正在尝试将我们的 Web 应用程序从 Wildfly 9.0.2 迁移到 Wildfly 10.1.0,然后从 Hibernate 4.3.10 迁移到 5.0.10

我们从未定义自己的NamingStrategy,使用 Hibernate 为我们的实体选择的任何名称(我们的 Postgresql 数据库是通过 构建的hbm2ddl)。

现在,使用 Hibernate 5,我们有未知的列错误,因为命名约定似乎已经改变。具体来说,在连接表中,列名现在基于真正的类而不是父类:例如,在我们有一个UserEntity继承自的地方AgentEntity,在我们得到一agentEntity_id列之前,现在它是一userEntity_id列。

我尝试了我们的 4 个现有的 Hibernate ImplicitNamingStrategies(jpa、legacy-jpa、legacy-hbm 和 component-path)persistence.xml,但没有成功:每个都与旧策略不同。

那么,有没有办法避免重写我自己的策略以保持与旧模型的一致性?

4

1 回答 1

1

我在迁移到 Hibernate 5 时遇到了同样的问题,尽管我们有一个 Oracle 后端。通过同时使用org.hibernate.boot.model.naming.ImplicitNamingStrategyorg.hibernate.boot.model.naming.PhysicalNamingStrategy.

这是我的应用程序上下文中我的 bean 定义的样子:

@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;
}

最烦人的部分是找出以何种方式应用哪些命名策略以及我必须自己实现的事实CustomNamingStrategy,因为 Hibernate 不提供PhysicalNamingStrategy与 legacy 的命名匹配的ImprovedNamingStrategy

以下是我的内容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);
    }
}

您可能必须调整正则表达式以满足您的确切需求,但这对我有用。

于 2017-04-25T02:57:57.533 回答