【问题标题】:NamingStrategy in Hibernate 5 compliant with Hibernate 4Hibernate 5 中的 NamingStrategy 与 Hibernate 4 兼容
【发布时间】:2017-09-08 11:45:40
【问题描述】:

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

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

现在,在 Hibernate 5 中,由于命名约定似乎发生了变化,我们遇到了未知的列错误。具体来说,在连接表中,列名现在基于真实类而不是父类:例如,我们有一个继承自 AgentEntityUserEntity,在我们得到一个 agentEntity_id 列之前,现在它是一个 userEntity_id列。

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

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

【问题讨论】:

    标签: jpa migration hibernate-4.x hibernate-5


    【解决方案1】:

    我在迁移到 Hibernate 5 时遇到了同样的问题,尽管我们有一个 Oracle 后端。通过使用 org.hibernate.boot.model.naming.ImplicitNamingStrategyorg.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 没有提供与传统 @ 的命名匹配的 PhysicalNamingStrategy 987654326@.

    这是我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);
        }
    }
    

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

    【讨论】:

    • 我同意,在我看来,Hibernate 也没有与他们的传统命名策略兼容的物理命名策略。您能分享一下您的 com.anyapp.CustomNamingStrategy 吗?
    • 我已将我的 CustomNamingStrategy 实现的内容添加到我的答案中
    猜你喜欢
    • 2020-05-26
    • 2013-07-20
    • 2016-06-25
    • 1970-01-01
    • 2018-05-07
    • 1970-01-01
    • 1970-01-01
    • 2016-08-31
    • 2020-02-23
    相关资源
    最近更新 更多