--无法识别Spring Data JDBC DM方言
目录
--无法识别Spring Data JDBC DM方言
一 相似问题
1 无法识别 Spring Data REST @Idclass
2 Spring JDBC和Firebird数据库
3 Spring Data JDBC/Spring Data JPA 与 Hibernate
二 问题描述
三 报错如下
1 报错截图
2 错误信息
四 工程配置如下
1 Maven依赖添加
五 解决方法
六 其它问题
1 达梦字字段长度固定
参考文献
无法识别Spring Data JDBC Firebird方言 - IT屋-程序员软件开发技术分享社区
spring.factories 的妙用_惘昔-CSDN博客
二 问题描述
我正在尝试使用Spring Data JDBC和Spring Boot连接到DM数据库. 我已经使用Spring Tools创建了一个简单的应用程序. Spring Data JDBC无法识别方言.我相信问题在于DialectResolver
不支持DM.
@Nullable
private static Dialect getDialect(Connection connection) throws SQLException {
DatabaseMetaData metaData = connection.getMetaData();
String name = metaData.getDatabaseProductName().toLowerCase(Locale.ENGLISH);
if (name.contains("hsql")) {
return HsqlDbDialect.INSTANCE;
} else if (name.contains("h2")) {
return H2Dialect.INSTANCE;
} else if (!name.contains("mysql") && !name.contains("mariadb")) {
if (name.contains("postgresql")) {
return PostgresDialect.INSTANCE;
} else if (name.contains("microsoft")) {
return SqlServerDialect.INSTANCE;
} else if (name.contains("db2")) {
return Db2Dialect.INSTANCE;
} else {
DialectResolver.LOG.info(String.format("Couldn't determine Dialect for \"%s\"", name));
return null;
}
} else {
return new MySqlDialect(getIdentifierProcessing(metaData));
}
}
三 报错如下
1 报错截图
2 错误信息
java.base@11.0.11/java.lang.Thread.run(Thread.java:834)
2021-12-22 19:56:38.216 [TID: N/A] [main] INFO logger_name:o.s.b.a.l.ConditionEvaluationReportLoggingListener -
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-12-22 19:56:38.390 [TID: N/A] [main] ERROR logger_name: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@499a93a9. Please provide a Dialect.
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@499a93a9. Please provide a Dialect.
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@499a93a9. Please provide a Dialect.
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:652)
... 34 common frames omitted
Caused by: org.springframework.data.jdbc.repository.config.DialectResolver$NoDialectException: Cannot determine a dialect for org.springframework.jdbc.core.JdbcTemplate@499a93a9. Please provide a Dialect.
四 工程配置如下
1 Maven依赖添加
<dependency>
<groupId>com.dameng</groupId>
<artifactId>Dm8JdbcDriver18</artifactId>
<version>8.1.1.49</version>
</dependency>
<dependency>
<groupId>com.dameng</groupId>
<artifactId>DmDialect-for-hibernate5.0</artifactId>
<version>8.1.1.49</version>
</dependency>
五 解决方法
Spring Data JDBC库本身不包含现成的DM,Firebird方言,因此您需要自己提供一个. 注释Spring JDBC文档的基于基础的配置:
方言由JdbcOperations
中的JdbcDialectResolver
解析, 通常通过检查Connection
.您可以让Spring自动发现 通过注册实现以下内容的类来创建Dialect
org.springframework.data.jdbc.repository.config.DialectResolver$JdbcDialectProvider
通过META-INF/spring.factories
. DialectResolver
发现 使用Spring的类路径从方言方中实现方言提供者 SpringFactoriesLoader
.
要使用DM,Firebird,您需要定义三件事:
- 方言
- 方言解析器
- Spring的配置文件以查找方言解析器
方言可以是类似的(请注意,该方言假定DM ,Firebird 3或更高版本):
package spring.dm;
import org.springframework.data.relational.core.dialect.AnsiDialect;
import org.springframework.data.relational.core.dialect.ArrayColumns;
import org.springframework.data.relational.core.dialect.LockClause;
import org.springframework.data.relational.core.sql.LockOptions;
public class DMDialect extends AnsiDialect {
public static final DMDialect INSTANCE = new DMDialect();
@Override
public LockClause lock() {
return LOCK_CLAUSE;
}
@Override
public ArrayColumns getArraySupport() {
return ArrayColumns.Unsupported.INSTANCE;
}
private static final LockClause LOCK_CLAUSE = new LockClause() {
@Override
public String getLock(LockOptions lockOptions) {
return "WITH LOCK";
}
@Override
public Position getClausePosition() {
return Position.AFTER_ORDER_BY;
}
};
}方言解析器,如果连接到Firebird数据库,则返回方言.
package spring.dm;
import org.springframework.data.jdbc.repository.config.DialectResolver;
import org.springframework.data.relational.core.dialect.Dialect;
import org.springframework.jdbc.core.ConnectionCallback;
import org.springframework.jdbc.core.JdbcOperations;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.Locale;
import java.util.Optional;
public class DMDialectResolver implements DialectResolver.JdbcDialectProvider {
@Override
public Optional<Dialect> getDialect(JdbcOperations jdbcOperations) {
return Optional.ofNullable(
jdbcOperations.execute((ConnectionCallback<Dialect>)DMDialectResolver::getDialect )
);
}
private static Dialect getDialect(Connection connection) throws SQLException {
DatabaseMetaData metaData = connection.getMetaData();
String name = metaData.getDatabaseProductName().toLowerCase( Locale.ROOT);
if (name.contains("dm dbms")) {
return DMDialect.INSTANCE;
}
return null;
}
}
最后,您需要在META-INF中定义一个名称为spring.factories的资源,该文件必须包含以下行
org.springframework.data.jdbc.repository.config.DialectResolver$JdbcDialectProvider=spring.firebird.FirebirdDialectResolver
这允许Spring Data JDBC发现方言解析器并使用它
六 其它问题
1 达梦字字段长度固定
达梦数据库字段长度不会自动增加,例如字符串长度50,存储字符串超过50会报错,mysql不会。