--无法识别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 报错截图

springboot 连接达梦数据库 jpa连接达梦数据库_达梦

 

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.factoriesDialectResolver发现 使用Spring的类路径从方言方中实现方言提供者 SpringFactoriesLoader.

要使用DM,Firebird,您需要定义三件事:

  1. 方言
  2. 方言解析器
  3. 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不会。

参考文献