메이쁘

[Spring] Spring Data JPA 사용 시 Hibernate에서 Column CamelCase -> SnakeCase 변환 안되는 문제 해결 본문

Technology/Web - Spring

[Spring] Spring Data JPA 사용 시 Hibernate에서 Column CamelCase -> SnakeCase 변환 안되는 문제 해결

메이쁘 2021. 5. 17. 21:13

안녕하세요.

 

제가 작성한 Entity 소스코드부터 보여드리자면,

@Getter
@Setter
@ToString
@Entity
@Table(name="members")	// DB에서 해당 이름의 테이블과 매칭
@ApiModel(value="LoginPVO", description="로그인 PVO")
public class LoginEntity implements Serializable {

	private static final long serialVersionUID = 1L;
	
	@Id	// Primary key
	@ApiModelProperty(value="아이디", required = true)
	private String emailId;
	@ApiModelProperty(value="비밀번호(해시)", required = true)
	private String pwd;
}

 

위와 같이 @Entity 어노테이션을 추가한 클래스는 @Table로 RDBMS에 담겨있는 Table명을, 전역변수들은 테이블 내의 Column 명을 맵핑하게 됩니다.

 

즉, 위와 같은 경우에는

이렇게 저장된 테이블과 맵핑이 되어야 합니다.

 

하지만, emilId 라는 변수가 members 테이블의 email_id 와 맵핑이 되지 않아서

java.sql.SQLException: isValid() returned false

실제 JPA로 실행된 Query문. snakeCase로 변경이 되지 않은듯...

 

 

오류를 뱉어내게 되었는데요.

 

 

 

구글링 결과,

 

1) hibernate 설정 파일에서 CamelCase -> SnakeCase 변환을 위해선 별도로 설정을 해야 한다는 것

2) hibernate 버전에 따라 설정 방법이 다르다는 것

 

을 알았습니다.

 

참고로 저는 hibernate 5.2.9.Final 버전을 사용하고 있습니다.

 

 

hibernate 5 버전을 기준으로 설정 방법이 다른데, hibernate 5 버전에서 적용하는 방법을 작성하겠습니다.

해당 버전부터는 별도의 클래스 파일을 만들어, 인터페이스를 구현해야합니다.

 
package com.artiplace.api.comn.util;

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 ImprovedNamingStrategy 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);
    }
}

위와 같이 java class 파일을 만들고,

해당 패키지 경로만 기억해두신 다음 설정 파일에서 

    <bean id ="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
	    <property name="dataSource"  ref="dataSource"></property>
	    <property name="jpaVendorAdapter"  ref="jpaVendorAdapter"></property>
	    <property name="packagesToScan" value="com.artiplace.api"></property>
		<property name="jpaProperties">
		   <props>
			   <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
			   <prop key="hibernate.show_sql">true</prop>
			   <prop key="hibernate.format_sql">true</prop>
			   <prop key="hibernate.use_sql_comments">true</prop>
			   <prop key="hibernate.hbm2ddl.auto">update</prop>
			   <prop key="hibernate.physical_naming_strategy">com.artiplace.api.comn.util.ImprovedNamingStrategy</prop>
		   </props>
		</property>
  	</bean>
  	 

jpaProperties 안에다가 

<prop key="hibernate.physical_naming_strategy">클래스파일 경로(패키지경로 + 파일이름)</prop>

 

 

 

추가해주시면 끝입니다.

 

 

결과는?

emailId -> email_id 로 변경된 Query문이 실행되었다!

 

 

 

이상입니다.

 

감사합니다.

 

 

 

 

참고

https://m.blog.naver.com/PostView.naver?blogId=z1004man&logNo=220968980085&proxyReferer=https:%2F%2Fwww.google.com%2F 

https://stackoverflow.com/questions/32165694/spring-hibernate-5-naming-strategy-configuration

Comments