Spring Data JDBC Firebird dialect not recognized Spring Data JDBC Firebird dialect not recognized spring spring

Spring Data JDBC Firebird dialect not recognized


The Spring Data JDBC library itself does not contain a Firebird dialect out of the box, so you need to provide one yourself. How to do this is documented in Annotation-based Configuration of the Spring Data JDBC documentation:

Dialects are resolved by JdbcDialectResolver from JdbcOperations, typically by inspecting Connection. You can let Spring auto-discover your Dialect by registering a class that implements org.springframework.data.jdbc.repository.config.DialectResolver$JdbcDialectProvider through META-INF/spring.factories. DialectResolver discovers dialect provider implementations from the class path using Spring’s SpringFactoriesLoader.

To be able to use Firebird, you will need to define three things:

  1. A dialect
  2. A dialect resolver
  3. A config file for Spring to locate the dialect resolver

The dialect can be something like (note, this dialect assumes Firebird 3 or higher):

package spring.firebird;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 FirebirdDialect extends AnsiDialect {    public static final FirebirdDialect INSTANCE = new FirebirdDialect();    @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;        }    };}

A dialect resolver to return the dialect if the connection is to a Firebird database.

package spring.firebird;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 FirebirdDialectResolver implements DialectResolver.JdbcDialectProvider {    @Override    public Optional<Dialect> getDialect(JdbcOperations operations) {        return Optional.ofNullable(                operations.execute((ConnectionCallback<Dialect>) FirebirdDialectResolver::getDialect));    }    private static Dialect getDialect(Connection connection) throws SQLException  {        DatabaseMetaData metaData = connection.getMetaData();        String name = metaData.getDatabaseProductName().toLowerCase(Locale.ROOT);        if (name.contains("firebird")) {            return FirebirdDialect.INSTANCE;        }        return null;    }}

Finally, you need to define a resource in META-INF with the name spring.factories, this file must contain the line:

org.springframework.data.jdbc.repository.config.DialectResolver$JdbcDialectProvider=spring.firebird.FirebirdDialectResolver

This allows Spring Data JDBC to discover the dialect resolver and use it.


I Solve the problem with my colleague,my solution is (remove the dependency spring-boot-stater-data-jdbc keep the dependency spring-boot-starter-jdbc)

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


Working solution for MariaDB / MySQL with Spring Boot 2.3.1.RELEASE

create directory/file if not exists: resources/META-INF/spring.factories

org.springframework.data.jdbc.repository.config.DialectResolver$JdbcDialectProvider=com.yourapp.config.MariaDbDialectResolver

create class:

package com.yourapp.config;import org.springframework.data.jdbc.repository.config.DialectResolver;import org.springframework.data.relational.core.dialect.Dialect;import org.springframework.data.relational.core.dialect.MySqlDialect;import org.springframework.jdbc.core.JdbcOperations;import java.util.Optional;public class MariaDbDialectResolver implements DialectResolver.JdbcDialectProvider {    @Override    public Optional<Dialect> getDialect(JdbcOperations jdbcOperations) {        return Optional.of(MySqlDialect.INSTANCE);    }}