발생 배경
spring boot, spring starter jpa, hibernate, mysql을 사용하여 jpa를 적용 하려고 했어요. 작업을 진행하는 과정에서 jpa를 통해 테이블 생성을 하기 위해 로컬 mysql으로 url을 설정하여 Entity 클래스를 정의하고, Querydsl까지 정상작동 하는것을 확인 했어요. 그 후 필요한 DB에 적용하기 위해 해당 테이블을 생성한 후, application.yml 파일에 spring.jpa.hibernate.ddl-auto: validate 설정을 했답니다.
아니 근데..! 아래와 같은 에러가 출력이 되더라구요!!!
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.GenericJDBCException: Error accessing tables metadata
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1762)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1105)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:139)
at com.wadiz.wave.searcher.SearcherApplication.main(SearcherApplication.java:31)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.GenericJDBCException: Error accessing tables metadata
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:402)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:377)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1821)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1758)
... 20 common frames omitted
Caused by: org.hibernate.exception.GenericJDBCException: Error accessing tables metadata
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99)
at org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl.convertSQLException(InformationExtractorJdbcDatabaseMetaDataImpl.java:98)
at org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl.populateTablesWithColumns(InformationExtractorJdbcDatabaseMetaDataImpl.java:383)
at org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl.getTables(InformationExtractorJdbcDatabaseMetaDataImpl.java:337)
at org.hibernate.tool.schema.extract.internal.DatabaseInformationImpl.getTablesInformation(DatabaseInformationImpl.java:120)
at org.hibernate.tool.schema.internal.GroupedSchemaValidatorImpl.validateTables(GroupedSchemaValidatorImpl.java:39)
at org.hibernate.tool.schema.internal.AbstractSchemaValidator.performValidation(AbstractSchemaValidator.java:89)
at org.hibernate.tool.schema.internal.AbstractSchemaValidator.doValidation(AbstractSchemaValidator.java:68)
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:191)
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:72)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:310)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:467)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:939)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:57)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:390)
... 24 common frames omitted
Caused by: java.sql.SQLException: Unknown error 1356
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
at com.mysql.cj.jdbc.StatementImpl.executeQuery(StatementImpl.java:1218)
at com.mysql.cj.jdbc.DatabaseMetaData$2.forEach(DatabaseMetaData.java:2124)
at com.mysql.cj.jdbc.DatabaseMetaData$2.forEach(DatabaseMetaData.java:2053)
at com.mysql.cj.jdbc.IterateBlock.doForAll(IterateBlock.java:56)
at com.mysql.cj.jdbc.DatabaseMetaData.getColumns(DatabaseMetaData.java:2229)
at org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl.populateTablesWithColumns(InformationExtractorJdbcDatabaseMetaDataImpl.java:350)
... 37 common frames omitted
해결 과정
로그 확인
로그레벨을 trace로 하여 확인을 해보았어요. 하지만 딱히 눈에 밟히는 로그는 없었답니다.
뷰테이블?
mysql 1356 error로 구글링을 해보면, 뷰에 update 방지 라던지.. mysql 유저 비밀번호 세팅 관련 이슈들만 나와서 관련이 없다고 생각 했어요. 따라서 관련 내용은 아예 배제 하였답니다.
mysql 버전 문제?
제가 개발 과정에서 연결했던 로컬 mysql은 8.0.33 버전 이에요. 하지만 개발 후에 변경하여 연결한 DB는 5.7.33버전 이었어요. 그래서 mysql 버전 문제일까? 싶어서 mysql jdbc connector 버전도 변경 해보고 했습니다...만.. 문제는 해결되지 않았어요.
디버깅 및 소스 분석
하는 수 없이 라이브러리 단 소스를 파봐야 했어요. 하나하나 차근 차근 파보니 DatabaseMetadata#getColums 메소드에서 오류가 발생 했어요! 하이버네이트에서 validation 체크를 위해 mysql jdbc의 DatabaseMetadata 클래스를 통해 테이블 별 컬럼 메타데이터를 statement 를 생성하여 가지고 오는데요, 그 목록중에 한개의 테이블에서 문제가 발생했어요.
문제가 발생한 쿼리는 아래와 같았어요.
SHOW FULL COLUMNS FROM `temp_view` FROM `temp_db` LIKE '%';
temp_view는 뷰 였는데요..! 뷰를 만들기 위해 조회하는 쿼리에서 참조하는 테이블이.. 과거에 드랍되어서 해당 뷰는 정상 조회가 되지 않는 뷰였어요..
따라서 해당 뷰를 제거하고 다시 어플리케이션을 올리니 정상적으로 validation 체크가 완료 되었습니다!!
아오!!!!!!
'SPRING' 카테고리의 다른 글
Spring Integration 개요 (0) | 2023.06.01 |
---|---|
SpringBoot JpaRepository 를 Dependency Scan 에서 찾지 못할때 (0) | 2022.11.10 |
Spring Retry (0) | 2022.05.18 |
Spring Batch FaultTolerance (장애 허용) (0) | 2021.12.13 |
Spring Envers 로 자동 이력 관리 (0) | 2021.06.20 |