2017-04-12 11 views
4

우리는 현재 Wildfly 9.0.2에서 Wildfly 10.1.0으로 웹 애플 리케이션을 이동하려고하고 있으므로 을 Hibernate 4.3.10에서 5.0.10으로 마이그레이션하려고합니다.Hibernate 5의 NamingStrategy는 Hibernate 4와 호환됩니다.

하이버 네이트가 우리 엔티티에 대해 선택하는 이름을 사용하여 우리 자신의 NamingStrategy을 정의한 적이 없다. 우리 PostgreSQL 데이터베이스는 hbm2ddl을 통해 구축된다.

이제 Hibernate 5에서는 명명 규칙이 변경된 것처럼 알려지지 않은 열 오류가 있습니다. 특히 조인 테이블에서 열 이름은 이제 부모 대신 실제 클래스를 기반으로합니다. 예를 들어, AgentEntity에서 상속받은 UserEntity이있는 경우, 열을 얻으려면 userEntity_id 열이됩니다.

persistence.xml에있는 기존의 네 개의 최대 절전 모드 ImplicitNamingStrategies (jpa, legacy-jpa, legacy-hbm 및 component-path)을 사용해 보았습니다. 각각 이전 전략과 다릅니다.

그렇다면 이전 모델을 준수하기 위해 내 자신의 전략을 다시 작성하지 않는 방법이 있습니까?

답변

1

오라클 백엔드가 있지만 동일한 문제가 Hibernate 5로 마이그레이션되었습니다. org.hibernate.boot.model.naming.ImplicitNamingStrategyorg.hibernate.boot.model.naming.PhysicalNamingStrategy을 모두 사용하여 Hibernate 4에서 사용했던 것과 비슷한 이름 지정 전략을 얻을 수있었습니다. 나는에 CustomNamingStrategy을 구현해야한다고

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

가장 짜증나는 부분은 전략을 명명하는 것은 어떤 방법으로 적용 할 알아이고 사실 : 여기

내 빈 정의 내 응용 프로그램 컨텍스트에서 모습입니다 하이버 네이트는 레거시 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