[JPA] Hibernate5 네이밍 룰 변경해서 적용하기(Camel -> Snake)

2022. 11. 18. 14:30Web/JAVA

1. Implict Naming Strategy (암시적 명칭 전략)

  • 해당 방식은 명시적으로 naming이 지정되지 않은 Entity들의 명칭을 만들어주는 방식이다.
  • @Table, @Column 등의 방법으로 명칭을 미리 지칭한 경우 해당 전략은 적용되지 않는다.
  • 해당 방법은 기본적으로 ImplictNamingStrategyJpaComliantImpl 방식을 따르며, JPA에 정의한 변수, 클래스 그대로 적용
  • 만약 사용자가 직접 전략을 구상하고 싶다면 ImplicitNamingStrategy 인터페이스나 해당 자식 클래스들을 상속받아 구현 적용
  • 예시) https://riptutorial.com/hibernate/example/10369/creating-and-using-a-custom-implicitnamingstrategy
 

hibernate Tutorial => Creating and Using a Custom...

Learn hibernate - Creating and Using a Custom ImplicitNamingStrategy

riptutorial.com

2. Physical Naming Strategy (물리적 명칭 전략)

만약 기존의 개발자가 Entity의 일부 컬럼은 @Column으로 명시했고 그 외의 경우는 따로 만든
CustomImplicitNamingStrategy를 적용했다고 가정하자. 그러던 중 DB변경으로 명칭 정책이 바뀜에
따라 Column과 Table 명칭을 Uppercase, Snake 표기법으로, 변경한다면 어떻게 해야 할까?
  • 단순히 몇개가 안되면 상관이 없겠지만, 수십, 수백개가 넘는 것들을 일일히 수정하는것은 너무 끔직한 일일것이다.
  • 하지만 물리적 명칭 전략은 위에 대해 훌륭한 대책이 된다.
  • 해당 전략은 명시적 또는 암시적으로 명칭이 결정되든 항상, 마지막으로 적용되기 때문이다.
  • 기본 값으로는 logical_name 즉, 명시적, 암시적 명칭을 그대로 사용하며, 이를 변경하려면 PhysicalNamingStrategy 인터페이스나 해당 자식들을 상속받아 정의하면 된다.
  • 아래의 예제는 Uppercase, snakecase를 적용한 모습니다.
//java
package JPA
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;  

public class UppercaseSnakePhysicalNamingStrategy implements PhysicalNamingStrategy {
    @Override
    public Identifier toPhysicalCatalogName(Identifier identifier, JdbcEnvironment jdbcEnvironment) {
        if (identifier == null) {
            return null;
        }
        return convertToSnakeUpperCase(identifier);
    }

    @Override
    public Identifier toPhysicalSchemaName(Identifier identifier, JdbcEnvironment jdbcEnvironment) {
        if (identifier == null) {
            return null;
        }
        return convertToSnakeUpperCase(identifier);
    }

    @Override
    public Identifier toPhysicalTableName(Identifier identifier, JdbcEnvironment jdbcEnvironment) {
        return convertToSnakeUpperCase(identifier);
    }

    @Override
    public Identifier toPhysicalSequenceName(Identifier identifier, JdbcEnvironment jdbcEnvironment) {
        return convertToSnakeUpperCase(identifier);
    }

    @Override
    public Identifier toPhysicalColumnName(Identifier identifier, JdbcEnvironment jdbcEnvironment) {
        return convertToSnakeUpperCase(identifier);
    }

    private Identifier convertToSnakeUpperCase(final Identifier identifier) {
        final String regex = "([a-z])([A-Z])";
        final String replacement = "$1_$2";
        final String newName = identifier.getText()
                .replaceAll(regex, replacement)
                .toUpperCase();
        return Identifier.toIdentifier(newName);
    }
}

3. 결론

  • Hibernate5으로 넘어오면서 org.hibernate.cfg.NamingStrategy는 더이상 사용하지 않는다.( 넣어도 적용 안됨)
  • org.hibernate.cfg.NamingStrategy는 이제 ImplicitNamingStrategy와 PhysicalNamingStrategy로 분리 대체되었다.
  • DB의 공통적인 명칭규직은 물리적 명칭 전략, 그 외의 경우는 명시적, 암시적 명칭 전략을 사용하는 것이 권장된다.