Spring

스프링 부트 2.3.0.RELEASE의 새로운 오류: Oracle 12.2.0.1 jdbcdriver에 대한 UnsatisfiedDependencyException이지만 mysql jdbcdriver에는 해당되지 않음

기록만이살길 2022. 12. 18. 03:56
반응형

스프링 부트 2.3.0.RELEASE의 새로운 오류: Oracle 12.2.0.1 jdbcdriver에 대한 UnsatisfiedDependencyException이지만 mysql jdbcdriver에는 해당되지 않음

1. 질문(문제점):

의존성으로 jdbc 및 Oracle jdbc만으로 새로운 부팅 프로젝트 생성

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jdbc</artifactId>
    </dependency>

    <dependency>
        <groupId>com.oracle</groupId>
        <artifactId>ojdbc8</artifactId>
        <version>12.2.0.1</version>
    </dependency>

application.properties 파일에서 데이터 소스를 구성하고 이 간단한 애플리케이션을 실행하면 아래 스택 추적으로 폭탄이 터집니다.

2020-05-25 15:07:16.769 WARN 11840 --- [ main] scaAnnotationConfigApplicationContext: 컨텍스트 초기화 중 예외 발생 - 새로 고침 시도 취소: org.springframework.beans.factory.UnsatisfiedDependencyException: 이름이 'jdbcConverter'로 정의된 bean 생성 오류 클래스 경로 리소스 [org/springframework/boot/autoconfigure/data/jdbc/JdbcRepositoriesAutoConfiguration$SpringBootJdbcConfiguration.class]: 'jdbcConverter' 메서드 매개변수 4를 통해 표현된 충족되지 않은 의존성; 중첩된 예외는 org.springframework.beans.factory.BeanCreationException: 클래스 경로 리소스 [org/springframework/boot/autoconfigure/data/jdbc/JdbcRepositoriesAutoConfiguration$SpringBootJdbcConfiguration.class]에 정의된 이름이 'jdbcDialect'인 빈 생성 오류입니다. 팩토리 메소드를 통한 Bean 인스턴스화에 실패했습니다. 중첩 예외는 org.springframework.beans.BeanInstantiationException입니다. [org.springframework.data.relational.core.dialect.Dialect] 인스턴스화 실패: 팩토리 메소드 'jdbcDialect'가 예외를 발생시켰습니다. 중첩 예외는 org.springframework.data.jdbc.repository.config.DialectResolver$NoDialectException: org.springframework.jdbc.core.JdbcTemplate@7fe083b1에 대한 방언을 결정할 수 없습니다. 방언을 입력하십시오. 2020-05-25 15:07:16.769 INFO 11840 --- [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - 종료 시작... 2020-05-25 15:07:17.023 INFO 11840 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - 종료 완료. 2020-05-25 15:07:17.

ApplicationContext를 시작하는 동안 오류가 발생했습니다. 조건 보고서를 표시하려면 '디버그'를 활성화한 상태에서 애플리케이션을 다시 실행하세요. 2020-05-25 15:07:17.035 ERROR 11840 --- [ main] osboot.SpringApplication
: 응용 프로그램 실행 실패

org.springframework.beans.factory.UnsatisfiedDependencyException: 클래스 경로 리소스 [org/springframework/boot/autoconfigure/data/jdbc/JdbcRepositoriesAutoConfiguration$SpringBootJdbcConfiguration.class]에 정의된 이름이 'jdbcConverter'인 빈을 생성하는 중 오류가 발생했습니다. 'jdbcConverter 메서드를 통해 표현된 만족되지 않은 의존성 ' 매개변수 4; 중첩 예외는 org.springframework.beans.factory.BeanCreationException: 클래스 경로 리소스 [org/springframework/boot/autoconfigure/data/jdbc/JdbcRepositoriesAutoConfiguration$SpringBootJdbcConfiguration.class]에 정의된 이름이 'jdbcDialect'인 빈 생성 오류: 팩토리를 통한 빈 인스턴스화 방법이 실패했습니다. 중첩 예외는 org.springframework.beans.BeanInstantiationException입니다. [org.springframework.data.relational.core.dialect를 인스턴스화하지 못했습니다. Dialect]: 팩토리 메서드 'jdbcDialect'에서 예외가 발생했습니다. 중첩 예외는 org.springframework.data.jdbc.repository.config.DialectResolver$NoDialectException: org.springframework.jdbc.core.JdbcTemplate@7fe083b1에 대한 방언을 결정할 수 없습니다. 방언을 입력하십시오. org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:798) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] org.springframework.beans.factory에서. support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:539) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java :1338) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at org. 1226) [spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE] at net.sincera.dbmigration.liquibasedemo.LiquibasedemoApplication.main(LiquibasedemoApplication.java:21) [classes/:na] 원인: org .springframework.beans.factory.BeanCreationException: 클래스 경로 리소스 [org/springframework/boot/autoconfigure/data/jdbc/JdbcRepositoriesAutoConfiguration$SpringBootJdbcConfiguration.class]에 정의된 이름이 'jdbcDialect'인 빈 생성 오류: 팩토리 메서드를 통한 빈 인스턴스화 실패; 중첩 예외는 org.springframework.beans.BeanInstantiationException입니다. [org.springframework.data.relational.core.dialect.Dialect] 인스턴스화 실패: 팩토리 메소드 'jdbcDialect'가 예외를 발생시켰습니다. 중첩 예외는 org.springframework.data.jdbc.repository.config.DialectResolver$NoDialectException입니다. org.springframework.jdbc.core.JdbcTemplate@7fe083b1의 방언을 결정할 수 없습니다. 방언을 입력하십시오. org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:656)에서 ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] org.springframework.beans.factory에서. support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:636) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java :1338) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177) ~[spring-beans- 5.2.6.RELEASE.jar:5.2.6. java:885) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:789) ~[spring-beans -5.2.6.RELEASE.jar:5.2.6.RELEASE] ... 19 공통 프레임 생략 원인: org.springframework.beans.BeanInstantiationException: 인스턴스화 실패 [org.springframework.data.relational.core.dialect.Dialect ]: 팩토리 메소드 'jdbcDialect'가 예외를 발생시켰습니다. 중첩 예외는 org.springframework.data.jdbc.repository.config.DialectResolver$NoDialectException: org.springframework.jdbc.core.JdbcTemplate@7fe083b1에 대한 방언을 결정할 수 없습니다. 방언을 입력하십시오. org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)에서 ~[spring-beans-5.2.6.RELEASE.jar:5.2.6. RELEASE] at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:651) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] ... 33개의 공통 프레임 생략 원인: org.springframework.data.jdbc.repository.config.DialectResolver$NoDialectException: org.springframework.jdbc.core.JdbcTemplate@7fe083b1의 방언을 결정할 수 없습니다. 방언을 입력하십시오. at org.springframework.data.jdbc.repository.config.DialectResolver.lambda$getDialect$2(DialectResolver.java:76) ~[spring-data-jdbc-2.0.0.RELEASE.jar:2.0.0.RELEASE] 자바에서 .util.Optional.orElseThrow(Optional.java:290) ~[na:1.8.0_241] at org.springframework.data.jdbc.repository.config.DialectResolver.getDialect(DialectResolver.java:75) ~[spring-data- jdbc-2.0.0.RELEASE.jar:2.0.0.RELEASE] org.springframework.data.jdbc.

스프링 부트 2.2.7.RELEASE를 사용하여 위의 코드를 실행하면 정상적으로 작동합니다. 예외는 없습니다!!

2일 후, 나는 localhost에 mysql 데이터 소스를 구성할 생각을 했다. 동일한 프로그램이 잘 실행되지만(스프링 부트 2.3.0.RELEASE 사용) 이번에는 mysql 데이터 소스를 사용했습니다.

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>

spring boot 2.3.0.RELEASE에서 oracle jdbc 드라이버에 무슨 일이 일어나고 있습니까?

스프링 부트 2.3.0.RELEASE에서 mysql jdbc 드라이버가 올바르게 작동하는 것은 무엇입니까?

감사합니다.

2. 해결방안:

spring boot 2.3.0.RELEASE에서 oracle jdbc 드라이버에 무슨 일이 일어나고 있습니까?

JDBC 드라이버가 제대로 작동하고 있습니다.

댓글에서 이미 배웠듯이 문제는

a) Spring Data JDBC는 이제 Dialect각 데이터베이스에 대해 필요합니다.

Dialectb) Spring Data JDBC는 for Oracle 과 함께 제공되지 않습니다 .

수정 사항:

Spring Data JDBC Firebird 방언이 인식되지 않음https://spring.io/blog/2020/05/20/migrating-to-spring-data-jdbc-2-0 에 설명된 대로 Dialect지금 당장 자체 구현을 제공해야 합니다. .

다음과 같이 작동합니다.

class MyOracleDialect extends AnsiDialect {

    private static final LimitClause LIMIT_CLAUSE = new LimitClause() {

        @Override
        public String getLimit(long limit) {
            return String.format("FETCH NEXT %d ROWS ONLY", limit);
        }

        @Override
        public String getOffset(long offset) {
            return String.format("OFFSET %d ROWS", offset);
        }

        @Override
        public String getLimitOffset(long limit, long offset) {
            return String.format("OFFSET %d ROWS FETCH NEXT %d ROWS ONLY", offset, limit);
        }

        @Override
        public Position getClausePosition() {
            return Position.AFTER_ORDER_BY;
        }
    };

    @Override
    public LimitClause limit() {
        return LIMIT_CLAUSE;
    }

}

그런 다음 참조된 Stackoverflow 질문에 설명된 대로 Dialecta를 통해 사용 가능 하게 만들어야 합니다 .DialectProvider

일부 배경:

지금까지 Spring Data 팀은 Oracle 데이터베이스와의 통합 테스트를 실행하지 않았습니다. 이는 빌드 인프라를 포함한 모든 코드가 오픈 소스이고 오라클이 데이터베이스 인스턴스나 해당 드라이버를 사용하기 위해 모든 종류의 항목을 수락해야 했기 때문에 꽤 오랫동안 합법적인 방법으로 이를 수행하는 방법이 불분명했기 때문입니다.

이제 Docker 이미지를 테스트에 사용할 수 있으며 JDBC 드라이버는 Maven Central에서 사용할 수 있습니다. 내가 알고 있는 도커 이미지에 대한 현재 옵션을 사용하면 많은 GB의 이미지 크기 또는 약 15분의 시작 시간 중에서 선택할 수 있기 때문에 여전히 약간 까다롭습니다.

어쨌든 문제를 해결하는 커뮤니티 회원이 있습니다: https://jira.spring.io/browse/DATAJDBC-256

따라서 가까운 시일 내에 Oracle을 완벽하게 지원할 수 있을 것이라고 확신합니다.

반응형