spring boot 2.3.0.RELEASE 中的新错误:Oracle 12.2.0.1 jdbcdriver 的 UnsatisfiedDependencyException 但不适用于 mysql jdbcdriver
New Error in spring boot 2.3.0.RELEASE : UnsatisfiedDependencyException for Oracle 12.2.0.1 jdbcdriver but not with mysql jdbcdriver
创建了一个新的引导项目,仅将 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]
s.c.a.AnnotationConfigApplicationContext : Exception encountered
during context initialization - cancelling refresh attempt:
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'jdbcConverter' defined in class path
resource
[org/springframework/boot/autoconfigure/data/jdbc/JdbcRepositoriesAutoConfiguration$SpringBootJdbcConfiguration.class]:
Unsatisfied dependency expressed through method 'jdbcConverter'
parameter 4; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'jdbcDialect' defined in class path resource
[org/springframework/boot/autoconfigure/data/jdbc/JdbcRepositoriesAutoConfiguration$SpringBootJdbcConfiguration.class]:
Bean instantiation via factory method failed; nested exception is
org.springframework.beans.BeanInstantiationException: Failed to
instantiate
[org.springframework.data.relational.core.dialect.Dialect]: Factory
method 'jdbcDialect' threw exception; nested exception is
org.springframework.data.jdbc.repository.config.DialectResolver$NoDialectException:
Cannot determine a dialect for
org.springframework.jdbc.core.JdbcTemplate@7fe083b1. Please provide a
Dialect. 2020-05-25 15:07:16.769 INFO 11840 --- [ main]
com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown
initiated... 2020-05-25 15:07:17.023 INFO 11840 --- [ main]
com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown
completed. 2020-05-25 15:07:17.028 INFO 11840 --- [ main]
ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report
re-run your application with 'debug' enabled. 2020-05-25 15:07:17.035
ERROR 11840 --- [ main] o.s.boot.SpringApplication
: Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'jdbcConverter' defined in class path
resource
[org/springframework/boot/autoconfigure/data/jdbc/JdbcRepositoriesAutoConfiguration$SpringBootJdbcConfiguration.class]:
Unsatisfied dependency expressed through method 'jdbcConverter'
parameter 4; nested exception is
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'jdbcDialect' defined in class path resource
[org/springframework/boot/autoconfigure/data/jdbc/JdbcRepositoriesAutoConfiguration$SpringBootJdbcConfiguration.class]:
Bean instantiation via factory method failed; nested exception is
org.springframework.beans.BeanInstantiationException: Failed to
instantiate
[org.springframework.data.relational.core.dialect.Dialect]: Factory
method 'jdbcDialect' threw exception; nested exception is
org.springframework.data.jdbc.repository.config.DialectResolver$NoDialectException:
Cannot determine a dialect for
org.springframework.jdbc.core.JdbcTemplate@7fe083b1. Please provide a
Dialect. at
org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:798)
~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at
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.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177)
~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557)
~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at
org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean[=16=](AbstractBeanFactory.java:323)
~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226)
~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at
org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:895)
~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at
org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878)
~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE] at
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE] at
org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758)
[spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE] at
org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750)
[spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE] at
org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
[spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE] at
org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
[spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE] at
org.springframework.boot.SpringApplication.run(SpringApplication.java:1237)
[spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE] at
org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
[spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE] at
net.sincera.dbmigration.liquibasedemo.LiquibasedemoApplication.main(LiquibasedemoApplication.java:21)
[classes/:na] Caused by:
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'jdbcDialect' defined in class path resource
[org/springframework/boot/autoconfigure/data/jdbc/JdbcRepositoriesAutoConfiguration$SpringBootJdbcConfiguration.class]:
Bean instantiation via factory method failed; nested exception is
org.springframework.beans.BeanInstantiationException: Failed to
instantiate
[org.springframework.data.relational.core.dialect.Dialect]: Factory
method 'jdbcDialect' threw exception; nested exception is
org.springframework.data.jdbc.repository.config.DialectResolver$NoDialectException:
Cannot determine a dialect for
org.springframework.jdbc.core.JdbcTemplate@7fe083b1. Please provide a
Dialect. at
org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:656)
~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at
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.RELEASE] at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557)
~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at
org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean[=16=](AbstractBeanFactory.java:323)
~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226)
~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at
org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)
~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at
org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1306)
~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at
org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1226)
~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at
org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.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 common frames
omitted Caused by:
org.springframework.beans.BeanInstantiationException: Failed to
instantiate
[org.springframework.data.relational.core.dialect.Dialect]: Factory
method 'jdbcDialect' threw exception; nested exception is
org.springframework.data.jdbc.repository.config.DialectResolver$NoDialectException:
Cannot determine a dialect for
org.springframework.jdbc.core.JdbcTemplate@7fe083b1. Please provide a
Dialect. at
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 common frames
omitted Caused by:
org.springframework.data.jdbc.repository.config.DialectResolver$NoDialectException:
Cannot determine a dialect for
org.springframework.jdbc.core.JdbcTemplate@7fe083b1. Please provide a
Dialect. at
org.springframework.data.jdbc.repository.config.DialectResolver.lambda$getDialect(DialectResolver.java:76)
~[spring-data-jdbc-2.0.0.RELEASE.jar:2.0.0.RELEASE] at
java.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] at
org.springframework.data.jdbc.repository.config.AbstractJdbcConfiguration.jdbcDialect(AbstractJdbcConfiguration.java:144)
~[spring-data-jdbc-2.0.0.RELEASE.jar:2.0.0.RELEASE] at
org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration$SpringBootJdbcConfiguration$$EnhancerBySpringCGLIB$30cfab.CGLIB$jdbcDialect()
~[spring-boot-autoconfigure-2.3.0.RELEASE.jar:2.3.0.RELEASE] at
org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration$SpringBootJdbcConfiguration$$EnhancerBySpringCGLIB$30cfab$$FastClassBySpringCGLIB$eb1865b.invoke()
~[spring-boot-autoconfigure-2.3.0.RELEASE.jar:2.3.0.RELEASE] at
org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244)
~[spring-core-5.2.6.RELEASE.jar:5.2.6.RELEASE] at
org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331)
~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE] at
org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration$SpringBootJdbcConfiguration$$EnhancerBySpringCGLIB$30cfab.jdbcDialect()
~[spring-boot-autoconfigure-2.3.0.RELEASE.jar:2.3.0.RELEASE] at
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
~[na:1.8.0_241] at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
~[na:1.8.0_241] at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
~[na:1.8.0_241] at java.lang.reflect.Method.invoke(Method.java:498)
~[na:1.8.0_241] at
org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] ... 34 common frames
omitted
如果我 运行 使用 spring boot 2.2.7.RELEASE 上面的代码,它工作得很好——没有例外!!
2 天后,我想到在本地主机上配置一个 mysql 数据源。同一个程序 运行 没问题(使用 spring boot 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 驱动程序发生了什么?
mysql jdbc 驱动程序在 spring boot 2.3.0.RELEASE 中的正确操作是什么?
谢谢。
此配置在我的设置中运行良好。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<version>2.3.0.RELEASE</version>
</dependency>
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<version>12.2.0.1</version>
</dependency>
</dependencies>
public class Demo {
private static String url = "jdbc:oracle:thin:user/pass@localhost:1521/XEPDB1";
public static void main( String[] args ) {
System.out.print( "Testing connection to database ..." );
try {
Connection conn = DriverManager.getConnection(url);
System.out.println("OK");
System.exit(0); // Prevent hang after completion when ran by mvn
} catch (SQLException ignore) {
System.out.println("ERROR: " + ignore);
System.exit(1); // Prevent hang after completion when ran by mvn
}
}
}
What is happening with the oracle jdbc driver in spring boot 2.3.0.RELEASE ?
JDBC 驱动程序运行良好。
正如您已经在评论中了解到的那样,问题在于
a) Spring 数据 JDBC 现在需要每个数据库Dialect
b) Spring 数据 JDBC 未随 Oracle Dialect
一起提供。
修复:
如 and in 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;
}
}
然后您需要通过 DialectProvider
使 Dialect
可用,如引用的 Whosebug 问题中所述:
一些背景:
到目前为止,Spring 数据团队没有 运行 他们与 Oracle 数据库的集成测试。
这是因为在很长一段时间内,不清楚如何以合法的方式做到这一点,因为包括构建基础设施在内的所有代码都是开源的,而 Oracle 需要接受各种东西才能使用数据库实例或其驱动程序。
现在 Docker 图像可用于测试,JDBC 驱动程序可从 Maven Central 获得。这仍然有点棘手,因为我知道 docker 图像的当前选项允许您在许多 GB 的图像大小或大约 15 分钟的启动时间之间进行选择。
无论如何,有一个社区成员正在处理这个问题:https://jira.spring.io/browse/DATAJDBC-256
因此,我相信我们将能够在不久的将来全面支持 Oracle。
上周我遇到了完全相同的问题。
我在项目中所做的更改更简单:我只是在 pom.xml:
中将 HikariCP 依赖项替换为 tomcat-jdbc
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
<!-- HikariCP doesn't deals with jdbcDialect properly -->
<exclusions>
<exclusion>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</exclusion>
</exclusions>
<!-- Dependency removed -->
</dependency>
<!-- Dependency to tomcat-jdbc to deal with jdbcDialect -->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</dependency>
<!--...-->
如果我撤消此操作,您在标题中发布的异常会再次发生。
祝你好运。
这些依赖项对我有用。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<version>19.6.0.0</version>
</dependency>
目前spring数据jdbc不支持oracle方言
您需要定义自己的方言解析器
为实现 JdbcDialectProvider
.
的 Oracle Dialect 添加以下 class
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.Locale;
import java.util.Optional;
import org.springframework.data.jdbc.repository.config.DialectResolver.JdbcDialectProvider;
import org.springframework.data.relational.core.dialect.AnsiDialect;
import org.springframework.data.relational.core.dialect.Dialect;
import org.springframework.jdbc.core.ConnectionCallback;
import org.springframework.jdbc.core.JdbcOperations;
public class OracleDialectResolver implements JdbcDialectProvider {
@Override
public Optional<Dialect> getDialect(JdbcOperations operations) {
return Optional.ofNullable(operations.execute((ConnectionCallback<Dialect>) OracleDialectResolver::getDialect));
}
private static Dialect getDialect(Connection connection) throws SQLException {
DatabaseMetaData metaData = connection.getMetaData();
String name = metaData.getDatabaseProductName().toLowerCase(Locale.ROOT);
if (name.contains("oracle")) {
return AnsiDialect.INSTANCE;
}
return null;
}
}
通过将文件 spring.factories
放入 class 路径的 META-INF
文件夹并添加以下行来注册您的提供商。
org.springframework.data.jdbc.repository.config.DialectResolver$JdbcDialectProvider=com.mypackage.jdbctemplate.dialect.OracleDialectResolver //fuly qualified class name of your dialect resolver class
此方言解析器解决了我与 Oracle 的问题。
@Configuration
public class SpringDataJdbcConfiguration extends AbstractJdbcConfiguration {
@Override
public Dialect jdbcDialect(NamedParameterJdbcOperations operations) {
return AnsiDialect.INSTANCE;
}
}
对已发布答案的小更新,适用于 oracle 方言
在
Build.gradle
implementation group: 'org.springframework.data', name: 'spring-data-relational', version: '2.1.1'
然后在下面创建class
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jdbc.repository.config.AbstractJdbcConfiguration;
import org.springframework.data.relational.core.dialect.OracleDialect;
import org.springframework.data.relational.core.dialect.Dialect;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
@Configuration
public class SpringDataJdbcConfiguration extends AbstractJdbcConfiguration {
@Override
public Dialect jdbcDialect(NamedParameterJdbcOperations operations) {
return OracleDialect.INSTANCE;
}
}
创建了一个新的引导项目,仅将 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] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'jdbcConverter' defined in class path resource [org/springframework/boot/autoconfigure/data/jdbc/JdbcRepositoriesAutoConfiguration$SpringBootJdbcConfiguration.class]: Unsatisfied dependency expressed through method 'jdbcConverter' parameter 4; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jdbcDialect' defined in class path resource [org/springframework/boot/autoconfigure/data/jdbc/JdbcRepositoriesAutoConfiguration$SpringBootJdbcConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.relational.core.dialect.Dialect]: Factory method 'jdbcDialect' threw exception; nested exception is org.springframework.data.jdbc.repository.config.DialectResolver$NoDialectException: Cannot determine a dialect for org.springframework.jdbc.core.JdbcTemplate@7fe083b1. Please provide a Dialect. 2020-05-25 15:07:16.769 INFO 11840 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated... 2020-05-25 15:07:17.023 INFO 11840 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed. 2020-05-25 15:07:17.028 INFO 11840 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled. 2020-05-25 15:07:17.035 ERROR 11840 --- [ main] o.s.boot.SpringApplication
: Application run failedorg.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'jdbcConverter' defined in class path resource [org/springframework/boot/autoconfigure/data/jdbc/JdbcRepositoriesAutoConfiguration$SpringBootJdbcConfiguration.class]: Unsatisfied dependency expressed through method 'jdbcConverter' parameter 4; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jdbcDialect' defined in class path resource [org/springframework/boot/autoconfigure/data/jdbc/JdbcRepositoriesAutoConfiguration$SpringBootJdbcConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.relational.core.dialect.Dialect]: Factory method 'jdbcDialect' threw exception; nested exception is org.springframework.data.jdbc.repository.config.DialectResolver$NoDialectException: Cannot determine a dialect for org.springframework.jdbc.core.JdbcTemplate@7fe083b1. Please provide a Dialect. at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:798) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at 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.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean[=16=](AbstractBeanFactory.java:323) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:895) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758) [spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750) [spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237) [spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE] at net.sincera.dbmigration.liquibasedemo.LiquibasedemoApplication.main(LiquibasedemoApplication.java:21) [classes/:na] Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jdbcDialect' defined in class path resource [org/springframework/boot/autoconfigure/data/jdbc/JdbcRepositoriesAutoConfiguration$SpringBootJdbcConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.relational.core.dialect.Dialect]: Factory method 'jdbcDialect' threw exception; nested exception is org.springframework.data.jdbc.repository.config.DialectResolver$NoDialectException: Cannot determine a dialect for org.springframework.jdbc.core.JdbcTemplate@7fe083b1. Please provide a Dialect. at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:656) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at 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.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean[=16=](AbstractBeanFactory.java:323) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1306) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1226) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.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 common frames omitted Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.relational.core.dialect.Dialect]: Factory method 'jdbcDialect' threw exception; nested exception is org.springframework.data.jdbc.repository.config.DialectResolver$NoDialectException: Cannot determine a dialect for org.springframework.jdbc.core.JdbcTemplate@7fe083b1. Please provide a Dialect. at 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 common frames omitted Caused by: org.springframework.data.jdbc.repository.config.DialectResolver$NoDialectException: Cannot determine a dialect for org.springframework.jdbc.core.JdbcTemplate@7fe083b1. Please provide a Dialect. at org.springframework.data.jdbc.repository.config.DialectResolver.lambda$getDialect(DialectResolver.java:76) ~[spring-data-jdbc-2.0.0.RELEASE.jar:2.0.0.RELEASE] at java.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] at org.springframework.data.jdbc.repository.config.AbstractJdbcConfiguration.jdbcDialect(AbstractJdbcConfiguration.java:144) ~[spring-data-jdbc-2.0.0.RELEASE.jar:2.0.0.RELEASE] at org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration$SpringBootJdbcConfiguration$$EnhancerBySpringCGLIB$30cfab.CGLIB$jdbcDialect() ~[spring-boot-autoconfigure-2.3.0.RELEASE.jar:2.3.0.RELEASE] at org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration$SpringBootJdbcConfiguration$$EnhancerBySpringCGLIB$30cfab$$FastClassBySpringCGLIB$eb1865b.invoke() ~[spring-boot-autoconfigure-2.3.0.RELEASE.jar:2.3.0.RELEASE] at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) ~[spring-core-5.2.6.RELEASE.jar:5.2.6.RELEASE] at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE] at org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration$SpringBootJdbcConfiguration$$EnhancerBySpringCGLIB$30cfab.jdbcDialect() ~[spring-boot-autoconfigure-2.3.0.RELEASE.jar:2.3.0.RELEASE] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_241] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_241] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_241] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_241] at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE] ... 34 common frames omitted
如果我 运行 使用 spring boot 2.2.7.RELEASE 上面的代码,它工作得很好——没有例外!!
2 天后,我想到在本地主机上配置一个 mysql 数据源。同一个程序 运行 没问题(使用 spring boot 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 驱动程序发生了什么?
mysql jdbc 驱动程序在 spring boot 2.3.0.RELEASE 中的正确操作是什么?
谢谢。
此配置在我的设置中运行良好。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<version>2.3.0.RELEASE</version>
</dependency>
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<version>12.2.0.1</version>
</dependency>
</dependencies>
public class Demo {
private static String url = "jdbc:oracle:thin:user/pass@localhost:1521/XEPDB1";
public static void main( String[] args ) {
System.out.print( "Testing connection to database ..." );
try {
Connection conn = DriverManager.getConnection(url);
System.out.println("OK");
System.exit(0); // Prevent hang after completion when ran by mvn
} catch (SQLException ignore) {
System.out.println("ERROR: " + ignore);
System.exit(1); // Prevent hang after completion when ran by mvn
}
}
}
What is happening with the oracle jdbc driver in spring boot 2.3.0.RELEASE ?
JDBC 驱动程序运行良好。
正如您已经在评论中了解到的那样,问题在于
a) Spring 数据 JDBC 现在需要每个数据库Dialect
b) Spring 数据 JDBC 未随 Oracle Dialect
一起提供。
修复:
如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;
}
}
然后您需要通过 DialectProvider
使 Dialect
可用,如引用的 Whosebug 问题中所述:
一些背景:
到目前为止,Spring 数据团队没有 运行 他们与 Oracle 数据库的集成测试。 这是因为在很长一段时间内,不清楚如何以合法的方式做到这一点,因为包括构建基础设施在内的所有代码都是开源的,而 Oracle 需要接受各种东西才能使用数据库实例或其驱动程序。
现在 Docker 图像可用于测试,JDBC 驱动程序可从 Maven Central 获得。这仍然有点棘手,因为我知道 docker 图像的当前选项允许您在许多 GB 的图像大小或大约 15 分钟的启动时间之间进行选择。
无论如何,有一个社区成员正在处理这个问题:https://jira.spring.io/browse/DATAJDBC-256
因此,我相信我们将能够在不久的将来全面支持 Oracle。
上周我遇到了完全相同的问题。
我在项目中所做的更改更简单:我只是在 pom.xml:
中将 HikariCP 依赖项替换为 tomcat-jdbc<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
<!-- HikariCP doesn't deals with jdbcDialect properly -->
<exclusions>
<exclusion>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</exclusion>
</exclusions>
<!-- Dependency removed -->
</dependency>
<!-- Dependency to tomcat-jdbc to deal with jdbcDialect -->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</dependency>
<!--...-->
如果我撤消此操作,您在标题中发布的异常会再次发生。
祝你好运。
这些依赖项对我有用。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<version>19.6.0.0</version>
</dependency>
目前spring数据jdbc不支持oracle方言
您需要定义自己的方言解析器
为实现 JdbcDialectProvider
.
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.Locale;
import java.util.Optional;
import org.springframework.data.jdbc.repository.config.DialectResolver.JdbcDialectProvider;
import org.springframework.data.relational.core.dialect.AnsiDialect;
import org.springframework.data.relational.core.dialect.Dialect;
import org.springframework.jdbc.core.ConnectionCallback;
import org.springframework.jdbc.core.JdbcOperations;
public class OracleDialectResolver implements JdbcDialectProvider {
@Override
public Optional<Dialect> getDialect(JdbcOperations operations) {
return Optional.ofNullable(operations.execute((ConnectionCallback<Dialect>) OracleDialectResolver::getDialect));
}
private static Dialect getDialect(Connection connection) throws SQLException {
DatabaseMetaData metaData = connection.getMetaData();
String name = metaData.getDatabaseProductName().toLowerCase(Locale.ROOT);
if (name.contains("oracle")) {
return AnsiDialect.INSTANCE;
}
return null;
}
}
通过将文件 spring.factories
放入 class 路径的 META-INF
文件夹并添加以下行来注册您的提供商。
org.springframework.data.jdbc.repository.config.DialectResolver$JdbcDialectProvider=com.mypackage.jdbctemplate.dialect.OracleDialectResolver //fuly qualified class name of your dialect resolver class
此方言解析器解决了我与 Oracle 的问题。
@Configuration
public class SpringDataJdbcConfiguration extends AbstractJdbcConfiguration {
@Override
public Dialect jdbcDialect(NamedParameterJdbcOperations operations) {
return AnsiDialect.INSTANCE;
}
}
对已发布答案的小更新,适用于 oracle 方言 在 Build.gradle
implementation group: 'org.springframework.data', name: 'spring-data-relational', version: '2.1.1'
然后在下面创建class
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jdbc.repository.config.AbstractJdbcConfiguration;
import org.springframework.data.relational.core.dialect.OracleDialect;
import org.springframework.data.relational.core.dialect.Dialect;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
@Configuration
public class SpringDataJdbcConfiguration extends AbstractJdbcConfiguration {
@Override
public Dialect jdbcDialect(NamedParameterJdbcOperations operations) {
return OracleDialect.INSTANCE;
}
}