eventuate-foundation / eventuate-common

Other
11 stars 20 forks source link

Spring Boot 2 vs. Spring Boot 3 - r2dbc spi incompatibility #132

Open kwonglau opened 1 year ago

kwonglau commented 1 year ago

Spring Boot 2 is using R2DBC SPI 0.8.x Spring Boot 3 is using 1.0.0.RELEASE

r2dbc has change the return type for insert row count from int to long. when using spring boot 3, we need to update the code and at least re-compile.

https://github.com/mirromutth/r2dbc-mysql the mysql r2dbc driver is not compatible with spring boot 3 and I mange to use the mariadb r2dbc driver (1.1.2) connecting to mysql server 8.0.31 and it is working well. when using 1.1.3, it throw exception, but 1.1.3 version can connect to mariadb 10.10.2 without any error.

However, the code need to be update like the following.

@Configuration
public class EventuateCommonReactiveMysqlConfiguration {

  @Bean
  @ConditionalOnProperty(name = "eventuate.reactive.db.driver", havingValue = MYSQL)
  public ConnectionFactory mysqlConnectionFactory(EventuateCommonReactiveDatabaseProperties eventuateCommonReactiveDatabaseProperties) {
//    ConnectionFactoryOptions options = ConnectionFactoryOptions.builder()
//        .option(DRIVER, eventuateCommonReactiveDatabaseProperties.getDriver())
//        .option(HOST, eventuateCommonReactiveDatabaseProperties.getHost())
//        .option(USER, eventuateCommonReactiveDatabaseProperties.getUsername())
//        .option(PORT, eventuateCommonReactiveDatabaseProperties.getPort())
//        .option(PASSWORD, eventuateCommonReactiveDatabaseProperties.getPassword())
//        .option(DATABASE, eventuateCommonReactiveDatabaseProperties.getDatabase())
//        .option(Option.valueOf("tcpKeepAlive"), true)
//        .build();
//        
//    return ConnectionFactories.get(options);

    MariadbConnectionConfiguration conf = MariadbConnectionConfiguration.builder()
        .host(eventuateCommonReactiveDatabaseProperties.getHost())
        .port(eventuateCommonReactiveDatabaseProperties.getPort())
        .username(eventuateCommonReactiveDatabaseProperties.getUsername())
        .password(eventuateCommonReactiveDatabaseProperties.getPassword())
        .database(eventuateCommonReactiveDatabaseProperties.getDatabase())
        .tcpKeepAlive(true)
        .allowPublicKeyRetrieval(true)
        .build();

    return new MariadbConnectionFactory(conf);
  }

}
cer commented 1 year ago

Perhaps the solution is for mysqlConnectionFactory() to use a plugin mechanism, e.g. Java SPI, i.e. find/load a Spring Boot version specific factory class for ConnectionFactory.

kwonglau commented 1 year ago

because of the SPI version different. We need to use different version of the r2dbc version when using different spring boot version e.g.

Postgres 1.0.0.RELEASE for SB3 and 0.9.3.RELEASE for SB2 Mariadb 1.1.2.RELEASE for SB3 and 1.0.2 for SB2

how do we deal with different version of the dependencies ?

cer commented 1 year ago

how do we deal with different version of the dependencies ?

I don't know the details but I'm guessing something like this:

cer commented 1 year ago

MariadbConnectionConfiguration conf = MariadbConnectionConfiguration.builder()

@kwonglau Why is a MariaDB specific API needed instead of a generic ConnectionFactoryOptions?

kwonglau commented 1 year ago

thanks for the idea. I'll try and see if this approach works.

cer commented 1 year ago

r2dbc has change the return type for insert row count from int to long. when using spring boot 3, we need to update the code and at least re-compile.

@kwonglau Where does this change need to be made?

kwonglau commented 1 year ago

because .option(Option.valueOf("allowPublicKeyRetrieval"), true) doesn't work since allowPublicKeyRetrieval is not a configuration param for mariadb. it can only be configured using the api explicitly.

cer commented 1 year ago

thanks for the idea. I'll try and see if this approach works.

BTW My preference would be to get the non-reactive Eventuate working with a Spring Boot 3 application before worrying about the reactive APIs. See comment about how the Eventuate libraries should be built/tested with Spring Boot 2 but work in a Spring Boot application.

kwonglau commented 1 year ago

will do