2017-04-12 99 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