title: Unable to execute any query using Oracle R2DBC driver with Spring Data reactive repositories
body: <p>I'm using SpringData Reactive Repositories for the first time.</p>
  <p>I've been going over the <a href="https://docs.spring.io/spring-data/r2dbc/docs/1.3.3/reference/html/#reference" rel="nofollow noreferrer">official documentation</a> and I created a basic CRUD API to use them.</p>
  <p>I started with H2, just for simplicity, and everything works as expected.</p>
  <p>When I try to create a new entity, everything works:</p>
  <pre class="lang-sh prettyprint-override"><code>% curl -v -# -X POST http://localhost:8080/wallet/
  *   Trying ::1:8080...
  * Connected to localhost (::1) port 8080 (#0)
  &gt; POST /wallet/ HTTP/1.1
  &gt; Host: localhost:8080
  &gt; User-Agent: curl/7.77.0
  &gt; Accept: */*
  &gt; 
  * Mark bundle as not supporting multiuse
  &lt; HTTP/1.1 201 Created
  &lt; Content-Type: application/json
  &lt; Content-Length: 57
  &lt; 
  * Connection #0 to host localhost left intact
  {&quot;id&quot;:&quot;6cccd902-01a4-4a81-8166-933b2a109ecc&quot;,&quot;balance&quot;:0}
  </code></pre>
  <p>The code is pretty simple (as usually with SpringData Repositories):</p>
  <pre class="lang-java prettyprint-override"><code>import com.jfcorugedo.reactivedemo.wallet.model.Wallet;
  import org.springframework.data.repository.reactive.ReactiveCrudRepository;
  
  public interface WalletRepository extends ReactiveCrudRepository&lt;Wallet, String&gt; {
  }
  </code></pre>
  <p>And the controller:</p>
  <pre class="lang-java prettyprint-override"><code>import com.jfcorugedo.reactivedemo.wallet.dao.WalletRepository;
  import com.jfcorugedo.reactivedemo.wallet.model.Wallet;
  import lombok.extern.slf4j.Slf4j;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.data.r2dbc.core.R2dbcEntityTemplate;
  import org.springframework.http.ResponseEntity;
  import org.springframework.web.bind.annotation.*;
  import reactor.core.publisher.Mono;
  
  import java.math.BigDecimal;
  
  import static org.springframework.data.relational.core.query.Query.query;
  
  @RestController
  @RequestMapping(&quot;wallet&quot;)
  @Slf4j
  public class WalletController {
  
      private WalletRepository walletRepository;
  
      @Autowired
      private R2dbcEntityTemplate template;
  
      public WalletController(WalletRepository walletRepository) {
          this.walletRepository = walletRepository;
      }
  
      @GetMapping(&quot;{id}&quot;)
      public Mono&lt;ResponseEntity&lt;Wallet&gt;&gt; get(@PathVariable(&quot;id&quot;) String id) {
  
          return walletRepository
                  .findById(id)
                  .map(ResponseEntity::ok)
                  .defaultIfEmpty(ResponseEntity.notFound().build());
      }
  
      @GetMapping(&quot;count&quot;)
      public Mono&lt;ResponseEntity&lt;Long&gt;&gt; count() {
  
          return walletRepository
                  .count()
                  .map(ResponseEntity::ok)
                  .defaultIfEmpty(ResponseEntity.notFound().build());
      }
  
      @PostMapping
      public Mono&lt;ResponseEntity&lt;Wallet&gt;&gt; create() {
  
          return walletRepository
                  .save(Wallet.empty())
                  .map(w -&gt; ResponseEntity.status(201).body(w));
      }
  
      @PostMapping(&quot;/entityTemplate&quot;)
      public Mono&lt;ResponseEntity&lt;Wallet&gt;&gt; insert() {
  
          log.info(&quot;Inserting using R2dbcEntityTemplate&quot;);
          return template.insert(new Wallet(null, BigDecimal.ZERO))
                  .map(ResponseEntity::ok);
      }
  }
  </code></pre>
  <p>The DTO is also quite simple:</p>
  <pre class="lang-java prettyprint-override"><code>import lombok.AllArgsConstructor;
  import lombok.Getter;
  import org.springframework.data.annotation.Id;
  
  import java.math.BigDecimal;
  
  @AllArgsConstructor
  @Getter
  public class Wallet {
  
      @Id
      private String id;
      private BigDecimal balance;
  
      public static Wallet empty() {
          return new Wallet(null, BigDecimal.ZERO);
      }
  
      public Wallet withId(String id) {
          return new Wallet(id, this.balance);
      }
  }
  </code></pre>
  <p>Then I check in the documentation that <a href="https://docs.spring.io/spring-data/r2dbc/docs/1.3.3/reference/html/#r2dbc.drivers" rel="nofollow noreferrer">Oracle is also supported</a>.</p>
  <p>And I went over the official <a href="https://github.com/oracle/oracle-r2dbc" rel="nofollow noreferrer">Oracle driver documentation</a>.</p>
  <p>It is true that this driver is under development, so it is not production-ready.</p>
  <p>However I clone the repository and I try to execute some tests over my local Oracle instance and everything works well.</p>
  <p>Here is the code I execute using Oracle driver directly:</p>
  <pre class="lang-java prettyprint-override"><code>String r2dbcUrl = &quot;r2dbc:oracle://?oracleNetDescriptor=&quot;+DESCRIPTOR;
      Mono.from(ConnectionFactories.get(ConnectionFactoryOptions.parse(r2dbcUrl)
        .mutate()
        .option(ConnectionFactoryOptions.USER, USER)
        .option(ConnectionFactoryOptions.PASSWORD, PASSWORD)
        .build())
        .create())
        .flatMapMany(connection -&gt;
          Mono.from(connection.createStatement(
            &quot;INSERT INTO WALLET (ID, BALANCE) VALUES ('&quot; + UUID.randomUUID().toString() + &quot;', 0)&quot;)
            .execute())
            .flatMapMany(result -&gt;
              result.map((row, metadata) -&gt; row.get(0, String.class)))
            .concatWith(Mono.from(connection.close()).cast(String.class)))
        .toStream()
        .forEach(System.out::println);
  
      // A descriptor may also be specified as an Option
      Mono.from(ConnectionFactories.get(ConnectionFactoryOptions.builder()
        .option(ConnectionFactoryOptions.DRIVER, &quot;oracle&quot;)
        .option(Option.valueOf(&quot;oracleNetDescriptor&quot;), DESCRIPTOR)
        .option(ConnectionFactoryOptions.USER, USER)
        .option(ConnectionFactoryOptions.PASSWORD, PASSWORD)
        .build())
        .create())
        .flatMapMany(connection -&gt;
          Mono.from(connection.createStatement(
            &quot;SELECT * from wallet&quot;)
            .execute())
            .flatMapMany(result -&gt;
              result.map((row, metadata) -&gt; row.get(0, String.class)))
            .concatWith(Mono.from(connection.close()).cast(String.class)))
        .toStream()
        .forEach(System.out::println);
  </code></pre>
  <p>I'm using the code Oracle developers provide in the sample folder.</p>
  <p>After executing this code, everything works and a new row is created in my WALLET table.</p>
  <p>Finally I try to do the same in SpringData.</p>
  <p>I used exactly the same DESCRIPTOR, USER and PASSWORD to connect to Oracle.</p>
  <p>This is the configuration class I'm using to get the ConnectionFactory:</p>
  <pre class="lang-java prettyprint-override"><code>package com.jfcorugedo.reactivedemo.config;
  
  import com.jfcorugedo.reactivedemo.wallet.model.Wallet;
  import io.r2dbc.spi.ConnectionFactories;
  import io.r2dbc.spi.ConnectionFactory;
  import io.r2dbc.spi.ConnectionFactoryOptions;
  import lombok.extern.slf4j.Slf4j;
  import org.springframework.beans.factory.annotation.Value;
  import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
  import org.springframework.context.annotation.Bean;
  import org.springframework.context.annotation.Configuration;
  import org.springframework.data.r2dbc.config.AbstractR2dbcConfiguration;
  import org.springframework.data.r2dbc.mapping.event.BeforeConvertCallback;
  
  import reactor.core.publisher.Mono;
  
  import java.util.UUID;
  
  @Configuration
  @ConditionalOnProperty(name = &quot;dababase.vendor&quot;, havingValue = &quot;oracle&quot;)
  @Slf4j
  public class OracleR2dbcConfig extends AbstractR2dbcConfiguration {
  
      @Value(&quot;${database.host:localhost}&quot;)
      private String host;
  
      @Value(&quot;${database.port:1521}&quot;)
      private int port;
  
      @Value(&quot;${database.serviceName}&quot;)
      private String serviceName;
  
      @Override
      @Bean(&quot;r2dbcConnectionFactory&quot;)
      public ConnectionFactory connectionFactory() {
          String descriptor = &quot;(DESCRIPTION=&quot; +
                  &quot;(ADDRESS=(HOST=&quot; + host + &quot;)(PORT=&quot; + port + &quot;)(PROTOCOL=tcp))&quot; +
                  &quot;(CONNECT_DATA=(SERVICE_NAME=&quot; + serviceName + &quot;)))&quot;;
  
          log.info(&quot;Creating connection factory with descriptor &quot; + descriptor);
  
          String r2dbcUrl = &quot;r2dbc:oracle://?oracleNetDescriptor=&quot;+descriptor;
          return ConnectionFactories.get(ConnectionFactoryOptions.parse(r2dbcUrl)
                  .mutate()
                  .option(ConnectionFactoryOptions.USER, &quot;jfcorugedo&quot;)
                  .option(ConnectionFactoryOptions.PASSWORD, System.getenv(&quot;DB_PASSWORD&quot;))
                  .build());
      }
  
      @Bean
      BeforeConvertCallback&lt;Wallet&gt; idGenerator() {
          return (entity, table) -&gt; entity.getId() == null ? Mono.just(entity.withId(UUID.randomUUID().toString())) : Mono.just(entity);
      }
  }
  </code></pre>
  <p>It is pretty similar to the one I used in the other project:</p>
  <pre class="lang-java prettyprint-override"><code>private static final String DESCRIPTOR = &quot;(DESCRIPTION=&quot; +
      &quot;(ADDRESS=(HOST=&quot;+HOST+&quot;)(PORT=&quot;+PORT+&quot;)(PROTOCOL=tcp))&quot; +
      &quot;(CONNECT_DATA=(SERVICE_NAME=&quot;+SERVICE_NAME+&quot;)))&quot;;
  ...
  String r2dbcUrl = &quot;r2dbc:oracle://?oracleNetDescriptor=&quot;+DESCRIPTOR;
      Mono.from(ConnectionFactories.get(ConnectionFactoryOptions.parse(r2dbcUrl)
        .mutate()
        .option(ConnectionFactoryOptions.USER, USER)
        .option(ConnectionFactoryOptions.PASSWORD, PASSWORD)
        .build())
        .create())
  ...
  </code></pre>
  <p>After switching to Oracle, SpringBoot application started without any error:</p>
  <pre><code>  .   ____          _            __ _ _
   /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
  ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
   \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
    '  |____| .__|_| |_|_| |_\__, | / / / /
   =========|_|==============|___/=/_/_/_/
   :: Spring Boot ::                (v2.5.3)
  
  2021-08-05 12:48:22.891  INFO 99453 --- [           main] c.j.r.ReactiveDemoApplication            : Starting ReactiveDemoApplication using Java 11.0.10 on APM3LC02CH2VNMD6R with PID 99453 (/Users/lp68ba/Developer/personal/reactive-demo/target/classes started by lp68ba in /Users/lp68ba/Developer/personal/reactive-demo)
  2021-08-05 12:48:22.892  INFO 99453 --- [           main] c.j.r.ReactiveDemoApplication            : No active profile set, falling back to default profiles: default
  2021-08-05 12:48:23.165  INFO 99453 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data R2DBC repositories in DEFAULT mode.
  2021-08-05 12:48:23.214  INFO 99453 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 45 ms. Found 1 R2DBC repository interfaces.
  2021-08-05 12:48:23.554  INFO 99453 --- [           main] c.j.r.config.OracleR2dbcConfig           : Creating connection factory with descriptor (DESCRIPTION=(ADDRESS=(HOST=localhost)(PORT=1521)(PROTOCOL=tcp))(CONNECT_DATA=(SERVICE_NAME=ORCLCDB)))
  2021-08-05 12:48:24.129  INFO 99453 --- [           main] o.s.b.web.embedded.netty.NettyWebServer  : Netty started on port 8080
  2021-08-05 12:48:24.142  INFO 99453 --- [           main] c.j.r.ReactiveDemoApplication            : Started ReactiveDemoApplication in 1.466 seconds (JVM running for 2.021)
  
  </code></pre>
  <p>However now when I try to execute any operation, the connections remains open and nothing happens:</p>
  <pre class="lang-sh prettyprint-override"><code>% curl -v -# -X POST http://localhost:8080/wallet/
  *   Trying ::1:8080...
  * Connected to localhost (::1) port 8080 (#0)
  &gt; POST /wallet/ HTTP/1.1
  &gt; Host: localhost:8080
  &gt; User-Agent: curl/7.77.0
  &gt; Accept: */*
  &gt; 
  </code></pre>
  <p>In the logs of the application I can see this trace:</p>
  <pre><code>2021-08-05 13:08:20.735 DEBUG 144 --- [nPool-worker-19] o.s.r2dbc.core.DefaultDatabaseClient     : Executing SQL statement [INSERT INTO WALLET (ID, BALANCE) VALUES (:P0_id, :P1_balance)]
  </code></pre>
  <p>However the execution never ends, and nothing is created in the database.</p>
  <p>I've tried with both: Spring Data Reactive Repositories and R2DBCEntityTemplate with same result.</p>
  <p>I've generated a custom version of the Oracle R2DBC Driver with some traces, and this is what I've got:</p>
  <p><strong>Using Oracle R2DBC Driver directly (everything works):</strong></p>
  <pre><code>Creating OracleConnectionFactoryImpl with options: ConnectionFactoryOptions{options={driver=oracle, oracleNetDescriptor=(DESCRIPTION=(ADDRESS=(HOST=localhost)(PORT=1521)(PROTOCOL=tcp))(CONNECT_DATA=(SERVICE_NAME=ORCLCDB))), password=REDACTED, user=jfcorugedo}}
  Oracel reactive adapter obtained: oracle.r2dbc.impl.OracleReactiveJdbcAdapter@c33b74f
  Datasource obtained: oracle.jdbc.pool.OracleDataSource@696da30b
  Creating a new connection
  using adatper y datasource to create a new connection
  Creating a OracleConnectionImpl with JDBC connection oracle.jdbc.driver.T4CConnection@10f7f7de
  createStatement(sql): INSERT INTO WALLET (ID, BALANCE) VALUES ('9a3ab3db-ec38-4544-ac87-4e1a4ad40343', 0)
  close()
  </code></pre>
  <p><strong>Using SpringData Reactive Repositories (the connection get stuck and nothing happens):</strong></p>
  <pre><code>  .   ____          _            __ _ _
   /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
  ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
   \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
    '  |____| .__|_| |_|_| |_\__, | / / / /
   =========|_|==============|___/=/_/_/_/
   :: Spring Boot ::                (v2.5.3)
  
  2021-08-05 13:12:49.557  INFO 304 --- [           main] c.j.r.ReactiveDemoApplication            : Starting ReactiveDemoApplication using Java 11.0.10 on APM3LC02CH2VNMD6R with PID 304 (/Users/lp68ba/Developer/personal/reactive-demo/target/classes started by lp68ba in /Users/lp68ba/Developer/personal/reactive-demo)
  2021-08-05 13:12:49.559  INFO 304 --- [           main] c.j.r.ReactiveDemoApplication            : No active profile set, falling back to default profiles: default
  2021-08-05 13:12:49.849  INFO 304 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data R2DBC repositories in DEFAULT mode.
  2021-08-05 13:12:49.891  INFO 304 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 38 ms. Found 1 R2DBC repository interfaces.
  2021-08-05 13:12:50.208  INFO 304 --- [           main] c.j.r.config.OracleR2dbcConfig           : Creating connection factory with descriptor (DESCRIPTION=(ADDRESS=(HOST=localhost)(PORT=1521)(PROTOCOL=tcp))(CONNECT_DATA=(SERVICE_NAME=ORCLCDB)))
  Creating OracleConnectionFactoryImpl with options: ConnectionFactoryOptions{options={driver=oracle, oracleNetDescriptor=(DESCRIPTION=(ADDRESS=(HOST=localhost)(PORT=1521)(PROTOCOL=tcp))(CONNECT_DATA=(SERVICE_NAME=ORCLCDB))), password=REDACTED, user=jfcorugedo}}
  Oracel reactive adapter obtained: oracle.r2dbc.impl.OracleReactiveJdbcAdapter@5f172d4a
  Datasource obtained: oracle.jdbc.pool.OracleDataSource@934b52f
  2021-08-05 13:12:50.736  INFO 304 --- [           main] o.s.b.web.embedded.netty.NettyWebServer  : Netty started on port 8080
  2021-08-05 13:12:50.745  INFO 304 --- [           main] c.j.r.ReactiveDemoApplication            : Started ReactiveDemoApplication in 1.417 seconds (JVM running for 4.428)
  Creating a new connection
  using adatper y datasource to create a new connection
  Creating a OracleConnectionImpl with JDBC connection oracle.jdbc.driver.T4CConnection@42dce884
  2021-08-05 13:12:54.481 DEBUG 304 --- [nPool-worker-19] o.s.r2dbc.core.DefaultDatabaseClient     : Executing SQL statement [INSERT INTO WALLET (ID, BALANCE) VALUES (:P0_id, :P1_balance)]
  OracleConnectionImpl#createStatement(sql): INSERT INTO WALLET (ID, BALANCE) VALUES (:P0_id, :P1_balance)
  Creating OracleStatementImpl with SQL: INSERT INTO WALLET (ID, BALANCE) VALUES (:P0_id, :P1_balance)
  OracleConnectionImpl#close()
  </code></pre>
  <p>I have no idea why the execution is getting stuck with SpringData. The connection seems to be ok and I'm using exactly the same parameters here than I used with Oracle Driver directly.</p>
  <p>Does someone have a working example using SpringData R2DBC repositories and Oracle R2DBC Driver?</p>
  <p>You can check the code in this <a href="https://github.com/jfcorugedo/reactive-demo" rel="nofollow noreferrer">repository</a>.</p>