[JPA] Error creating bean with name 'entityManagerFactory' defined in class path resource 에러 해결
spring 버전 : 2.2.4
gradle 버전 : 6.4.1
//postgresql 의존성 추가
compile group: 'org.postgresql', name: 'postgresql'
JPA + Spring Boot + H2
를 사용하는 프로젝트에서
PostgreSql를 연동하려고 접속 정보를 입력 후 메인을 실행시켰는데 아래와 같은 에러가 발생했다.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.SQLGrammarException: Unable to build DatabaseInformation
현재 yml 설정은 아래와 같은 상태였다.
에러 내용을 검색해보니
- javaassist 의존성을 추가해라
- yml에
database-platform: org.hibernate.dialect.PostgreSQLDialect
옵션을 추가해라
등등의 해결책이 있었지만, 도움이 되지는 않았다.
현재 총 6개의 테이블이 생성되어야하는데 5개 밖에 생성되지 않은 상태이다.
테이블을 drop 후 실행해도 동일한 증상이었다.
ddl-auto 옵션을 create로 주고 재실행하면 create쿼리가 정상적으로 날라가는데 그 아래 명확한 에러가 있었다.
Caused by: org.postgresql.util.PSQLException: ERROR: type "clob" does not exist
account Entity의 Lob
타입 칼럼이 문제의 원인이었다.
@Lob @Basic(fetch = FetchType.EAGER)
private String profileImage;
h2 디비에서는 전혀 문제가 되지 않았는데, postgresql에서는 clob을 지원하지 않았다.
The clob data type is unsupported in Postgres. However, it can be easily defined as a synonym to the text type: create domain clob as text;
해결 방법
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation property를 true로 설정하면 hibernate의 jdbc 환경 설정 부분에서 CLOB 객체를 생성하는 함수에서 개별 Database의 구현 함수 부분을 호출하는 것을 아래와 같이 막고 있다. 이 때문에 Log로 Warning Message만 하나 남기고 초기화 과정이 끝나게 된다.
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults= false;
이 설정을 이용하게 되면 Jdbc 환경구성을 하는 과정에서 Default Metadata를 사용할 지 여부에 따라 분기하게 된다. 분기의 시작점은 JdbcEnvironmentInitiator class의 initiateService 함수에서 시작되게 된다. 이 함수에서 JdbcEnvironmentImpl Class를 Instance화 할 때 다른 생성자 함수를 호출하게 된다.
응? 이건 이미 처음부터 지정한 설정이었는데?
다시 로그를 천천히 보니 h2 DB 엔진으로 쿼리가 돌아가고있었다.
data-platform 옵션이 제대로 적용이 되지않았다.
spring.jpa.properties.hibernate.dialect: org.hibernate.dialect.PostgreSQLDialect
dialect 옵션을 위와 같이 수정해줬더니 PostgreSQLDialect 엔진으로 제대로 동작했고, 정상동작했다.
깰-끔
참고