이전에 정리한 오류가 또 다시 났다. 이번엔 테스트에서 문제가 생긴게 아니라 스프링 부트 프로젝트를 실제로 구동할 때 문제가 발생했다. 원인을 확인하려고 JPA가 생성하는 SQL을 확인했다. 그 결과 JPA가 생성해주는 SQL문에서의 Table이름과 프로젝트를 위해 구축한 데이터베이스에서의 Table이름이 달랐다. 예를 들어 JPA가 생성해주는 SQL문에서의 Table이름은 member_item
이라면 우리가 구축한 테이블의 이름은 memberItem
이었다.
왜 JPA는 카멜케이스로 테이블 이름을 안 만들고 언더스코어로 테이블 이름을 생성하나 궁금해서 김영한님의 자바 ORM 표준 JPA 프로그래밍
책을 다시 읽었다. 확인해보니 자바 언어는 관례상 카멜 케이스를 주로 사용하고, 데이터베이스는 관례상 언더스코어를 자주 사용한다고 한다. 그래서 JPA가 SQL을 생성할 때 자바의 카멜케이스명명법을 데이터베이스의 이름 관례 규칙에 맞게 언더스코어로 변환해준 것이었다. 데이터베이스를 구축할 때 데이터베이스 관례를 알지 못하고 테이블명을 모두 카멜케이스로 지어버린 것에서 발생한 문제였다. 문제를 해결하는데는 3가지 방법이 있었다.
@Table
, @Column
어노테이션의 name
속성을 사용해서 프로젝트의 필드명과 데이터베이스의 테이블, 테이블 컬럼을 매핑시킨다.위의 3가지 방법 중 마지막 방법이 문제를 빠르게 해결할 수 있고 프로젝트 팀원들도 카멜케이스 명명법에 많이 익숙해져 있기 때문에 더 안전성 있는 해결법이라고 판단했다. 그래서 application.properties
에 아래의 설정을 추가했다.
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
위 설정을 추가하면 JPA가 자바의 카멜케이스 명명법을 언더스코어로 바꾸지 않고, 내가 지정한 스프링 부트 프로젝트에서의 필드명을 그대로 사용해서 SQL을 생성한다. 스프링 부트 프로젝트의 모든 필드명과 데이터베이스의 모든 Table명, Column명을 카멜케이스로 명명한 우리 프로젝트엔 적합한 해결책이라서 위의 설정을 추가하는 것으로 오류를 해결했다.
Caused by: java.sql.SQLSyntaxErrorException: Table 'DBNAME.TableName' doesn't exist