2017-04-12 98 views
4

我们正在尝试将我们的Web应用程序从Wildfly 9.0.2迁移到Wildfly 10.1.0,因此将从Hibernate 4.3.10迁移到5.0.10Hibernate 5中的NamingStrategy与Hibernate 4兼容4

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

现在,随着Hibernate 5,我们有未知的列错误,因为命名约定似乎已经改变。具体而言,在连接表中,列名现在基于真实类而不是父级:例如,在列之前,我们有一个UserEntity,它继承自AgentEntity,现在它是userEntity_id列。

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

那么,有没有办法避免重写我自己的策略来遵守我们的旧模型?

回答

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没有提供与传统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); 
    } 
} 

您可能需要调整正则表达式,以适应您的需求,但是这是对我工作。

+0

我同意了,在我看来,Hibernate并没有一个符合其原有命名策略的物理命名策略。你能否分享你的com.anyapp.CustomNamingStrategy? –

+1

我已将我的CustomNamingStrategy实现的内容添加到我的答案中 – lax1089