jpa – Hibernate 5中的NamingStrategy与Hibernate 4兼容

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

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

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

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

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

最佳答案 我有同样的问题迁移到Hibernate 5,虽然我们有一个Oracle后端.通过使用org.hibernate.boot.model.naming.ImplicitNamingStrategy和org.hibernate.boot.model.naming.PhysicalNamingStrategy,我能够实现与Hibernate 4开箱即用的类似命名策略.

这是我的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没有提供与传统ImprovedNamingStrategy的命名相匹配的PhysicalNamingStrategy.

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

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

点赞