R2DBC Driver for Oracle Database

Overview

About Oracle R2DBC

The Oracle R2DBC Driver is a Java library that supports reactive programming with Oracle Database.

Oracle R2DBC implements the R2DBC Service Provider Interface (SPI) as specified by the Reactive Relational Database Connectivity (R2DBC) project. The R2DBC SPI exposes Reactive Streams as an abstraction for remote database operations. Reactive Streams is a well defined standard for asynchronous, non-blocking, and back-pressured communication. This standard allows an R2DBC driver to interoperate with other reactive libraries and frameworks, such as Spring, Project Reactor, RxJava, and Akka Streams.

Oracle R2DBC 0.1.0 is the initial release of this driver. Release numbers follow the Semantic Versioning specification. As indicated by the major version number of 0, this is a development release in which the behavior implemented for any API may change.

Learn More About R2DBC:

R2DBC Project Home Page

R2DBC Javadocs v0.8.2

R2DBC Specification v0.8.2

Learn More About Reactive Streams:

Reactive Streams Project Home Page

Reactive Streams Javadocs v1.0.3

Reactive Streams Specification v1.0.3

Installation

Oracle R2DBC can be built from source using Maven:

mvn clean install -DskipTests=true

Omitting -DskipTests=true from the command above will execute the test suite, where end-to-end tests connect to an Oracle Database instance. The connection configuration is read from src/test/resources/config.properties.

Artifacts can also be found on Maven Central.

<dependency>
  <groupId>com.oracle.database.r2dbc</groupId>
  <artifactId>oracle-r2dbc</artifactId>
  <version>${version}</version>
</dependency>

Oracle R2DBC is compatible with JDK 11 (or newer), and has the following runtime dependencies:

  • R2DBC SPI 0.8.2
  • Reactive Streams 1.0.3
  • Project Reactor 3.0.0
  • Oracle JDBC 21.1.0.0 for JDK 11 (ojdbc11.jar)
    • Oracle R2DBC relies on the Oracle JDBC Driver's Reactive Extensions APIs. These APIs were introduced in the 21.1 release of Oracle JDBC, and are only available with the JDK 11 build (ojdbc11).

The Oracle R2DBC Driver has been verified with Oracle Database versions 19c and 21c.

Code Examples

The following code example uses the Oracle R2DBC Driver with Project Reactor's Mono and Flux types to open a database connection and execute a SQL query:

ConnectionFactory connectionFactory = ConnectionFactories.get(
  "r2dbc:oracle://db.example.com:1521/db.service.name");

Mono.from(connectionFactory.create())
  .flatMapMany(connection ->
    Flux.from(connection.createStatement(
      "SELECT 'Hello, Oracle' FROM sys.dual")
      .execute())
      .flatMap(result ->
        result.map((row, metadata) -> row.get(0, String.class)))
      .doOnNext(System.out::println)
      .thenMany(connection.close()))
  .subscribe();

When executed, the code above will asynchronously print the result of the SQL query.

The next example includes a named parameter marker, ":locale_name", in the SQL command:

Mono.from(connectionFactory.create())
  .flatMapMany(connection ->
    Flux.from(connection.createStatement(
      "SELECT greeting FROM locale WHERE locale_name = :locale_name")
      .bind("locale_name", "France")
      .execute())
      .flatMap(result ->
        result.map((row, metadata) ->
          String.format("%s, Oracle", row.get("greeting", String.class))))
      .doOnNext(System.out::println)
      .thenMany(connection.close()))
  .subscribe();

Like the previous example, executing the code above will asynchronously print a greeting message. "France" is set as the bind value for locale_name, so the query should return a greeting like "Bonjour" when row.get("greeting") is called.

Help

For help programming with Oracle R2DBC, ask questions on Stack Overflow tagged with [oracle] and [r2dbc]. The development team monitors Stack Overflow regularly.

Issues may be opened as described in our contribution guide.

Contributing

This project welcomes contributions from the community. Before submitting a pull request, please review our contribution guide.

Security

Please consult the security guide for our responsible security vulnerability disclosure process.

License

Copyright (c) 2021 Oracle and/or its affiliates.

This software is dual-licensed to you under the Universal Permissive License (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl or Apache License 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose either license.

Documentation

This document specifies the behavior of the R2DBC SPI implemented for the Oracle Database. This SPI implementation is referred to as the "Oracle R2DBC Driver" or "Oracle R2DBC" throughout the remainder of this document.

The Oracle R2DBC Driver implements behavior specified by the R2DBC 0.8.2 Specification and Javadoc

Publisher objects created by Oracle R2DBC implement behavior specified by the Reactive Streams 1.0.3 Specification and Javadoc

The R2DBC and Reactive Streams specifications include requirements that are optional for a compliant implementation. The remainder of this document specifies the Oracle R2DBC Driver's implementation of these optional requirements.

Connection Creation

Thread Safety and Parallel Execution

  • Oracle R2DBC's ConnectionFactory and ConnectionFactoryProvider are thread safe.
  • All other SPI implementations are not thread safe.
  • Executing parallel database calls is not supported over a single Connection. If a thread attempts to initiate a parallel call, that thread is blocked until the connection is no longer executing any other call. This is a limitation of the Oracle Database, which does not support parallel calls within a single session.

Reactive Streams

  • The Oracle R2DBC javadoc of every method that returns a Publisher specifies the behavior of that Publisher in regards to deferred execution and multiple Subscribers.
  • Typically, a Publisher of one or zero items defers execution until a Subscriber subscribes, supports multiple Subscribers, and caches the result of a database call (the same result of the same call is emitted to each Subscriber).
  • Typically, a Publisher of multiple items defers execution until a Subscriber signals demand, and does not support mulitple subscribers.

Errors

Transactions

  • READ COMMITTED is the default transaction isolation level, and is the only level supported in this release.
  • Transaction savepoints are not supported in this release.

Statements

  • Batch execution is only supported for DML type SQL commands (INSERT/UPDATE/DELETE).
  • SQL commands may contain JDBC style parameter markers where question mark characters (?) designate unnamed parameters. A numeric index must be used when setting the bind value of an unnamed parameter.
  • SQL commands may contain named parameter markers where the colon character (:) is followed by an alphanumeric parameter name. A name or numeric index may be used when setting the bind value of a named parameter.
  • Parameter names are case-sensitive.
  • The ROWID of each row affected by an INSERT or UPDATE is returned as the generated value for the empty set of column names.
  • A blocking database call is executed by a Statement returning generated values for a non-empty set of column names.
    • The blocking database call is a known limitation that will be resolved with a non-blocking implementation of java.sql.Connection.prepareStatement(String, String[]) in the Oracle JDBC Driver. The Oracle JDBC Team is aware of this problem and is working on a fix.

Type Mappings

  • Blob and Clob objects are the default mapping implemented by Row.get(...) for BLOB and CLOB columns. ByteBuffer and String mappings are not supported for BLOB and CLOB.
    • Oracle Database allows BLOBs and CLOBs to store terabytes of data; This amount would exceed the capacity of a ByteBuffer or String.
    • Blob and Clob objects stream data over a series of ByteBuffers or Strings.
    • Requiring content to be streamed over multiple buffers is necessary for Oracle R2DBC to avoid a potentially memory exhausting implementation in which BLOBs and CLOBs must be fully materialized as a return value for Row.get(...).
  • javax.json.JsonObject and oracle.sql.json.OracleJsonObject are supported as Java type mappings for JSON column values.
  • java.time.Duration is supported as a Java type mapping for INTERVAL DAY TO SECOND column values.
  • java.time.Period is supported as a Java type mapping for INTERVAL YEAR TO MONTH column values.
  • java.time.LocalDateTime is supported as a Java type mapping for DATE column values. The Oracle Database type named "DATE" stores the same information as a LocalDateTime: year, month, day, hour, minute, and second.

Secure Programming Guidelines

The following security guidelines should be followed when programming with the Oracle R2DBC Driver.

Defend Against SQL Injection Attacks

  • Always specify the parameters of a SQL command using the bind methods of io.r2dbc.spi.Statement.
    • Do not use String concatenation to specify parameters of a SQL command.
    • Do not use format Strings to specify parameters of a SQL command.

Protect Passwords

  • Do not hard code passwords in your source code.
  • Avoid hard coding passwords in the R2DBC URL.
    • When handling URL strings in code, be aware that a clear text password may appear in the user info section.
  • Use a sensitive io.r2dbc.spi.Option to specify passwords.
    • If possible, specify the Option's value as an instance of java.nio.CharBuffer or java.lang.StringBuffer and clear the contents immediately after ConnectionFactories.get(ConnectionFactoryOptions) has returned. Oracle R2DBC's implementation of ConnectionFactory does not retain a reference to the clear text password.

Protect Network Communications

  • Use SSL/TLS if possible. Use any of the following methods to enable SSL/TLS:
    • Specify the boolean value of true for io.r2dbc.spi.ConnectionFactoryOptions.SSL
    • Specify "r2dbcs:" as the R2DBC URL schema.
    • Specify "ssl=true" in the query section of the R2DBC URL.
  • Use Option.sensitiveValueOf(String) when creating an Option that specifies a password.
    • Option.sensitiveValueOf(OracleConnection.CONNECTION_PROPERTY_WALLET_PASSWORD)
      • An SSO wallet does not require a password.
    • Option.sensitiveValueOf(OracleConnection.CONNECTION_PROPERTY_THIN_JAVAX_NET_SSL_KEYSTOREPASSWORD)
    • Option.sensitiveValueOf(OracleConnection.CONNECTION_PROPERTY_THIN_JAVAX_NET_SSL_TRUSTSTOREPASSWORD)

Defend Against Denial-of-Service Attacks

  • Use a connection pool and configure a maximum size to limit the amount of database sessions created by ConnectionFactory.create()
  • Enforce a maximum batch size to limit invocations of Statement.add() or Batch.add(String).
  • Enforce a maximum fetch size to limit values supplied to Statement.fetchSize(int).
  • Enforce a maximum buffer size to limit memory usage when reading Blob and Clob objects.
Comments
  • Error when using r2dbc-pool: this publisher does not support multiple subscribers

    Error when using r2dbc-pool: this publisher does not support multiple subscribers

    I'm trying to use this driver with spring-boot-data-r2dbc (v2.4.4), but when I configure the connection factory to use the connection pool like this:

    return ConnectionFactories.get(ConnectionFactoryOptions.builder()
                    .option(ConnectionFactoryOptions.DRIVER, "pool")
                    .option(ConnectionFactoryOptions.PROTOCOL, "oracle")
                    .option(ConnectionFactoryOptions.HOST, "127.0.0.1")
                    .option(ConnectionFactoryOptions.PORT, 1521)
                    .option(ConnectionFactoryOptions.DATABASE, "XE")
                    .option(ConnectionFactoryOptions.USER, "APP_USER")
                    .option(ConnectionFactoryOptions.PASSWORD, "********************")
                    .option(Option.valueOf(OracleConnection.CONNECTION_PROPERTY_FAN_ENABLED), "false")
                    .build());
    

    With this settings:

    application.yaml
    
    spring:
      r2dbc:
        pool:
          initialSize: 10
          maxSize: 50
    

    Around 80% of my application requests ends with the following error:

    java.lang.IllegalStateException: This publisher does not support multiple subscribers.
    	at oracle.jdbc.datasource.impl.OracleDataSource$ConnectionPublisher.rejectSubscriber(OracleDataSource.java:2676) ~[ojdbc11-21.1.0.0.jar:21.1.0.0.0]
    	at oracle.jdbc.datasource.impl.OracleDataSource$ConnectionPublisher.subscribe(OracleDataSource.java:2655) ~[ojdbc11-21.1.0.0.jar:21.1.0.0.0]
    	at org.reactivestreams.FlowAdapters$ReactivePublisherFromFlow.subscribe(FlowAdapters.java:355) ~[reactive-streams-1.0.3.jar:na]
    	at oracle.r2dbc.impl.OracleReactiveJdbcAdapter.lambda$deferOnce$22(OracleReactiveJdbcAdapter.java:1071) ~[oracle-r2dbc-0.1.0.jar:0.1.0]
    	at oracle.r2dbc.impl.OracleReactiveJdbcAdapter$$Lambda$1775/00000000C46540E0.accept(Unknown Source) ~[na:na]
    	at java.base/java.util.concurrent.CompletableFuture.uniAcceptNow(CompletableFuture.java:753) ~[na:na]
    	at java.base/java.util.concurrent.CompletableFuture.uniAcceptStage(CompletableFuture.java:731) ~[na:na]
    	at java.base/java.util.concurrent.CompletableFuture.thenAccept(CompletableFuture.java:2172) ~[na:na]
    	at oracle.r2dbc.impl.OracleReactiveJdbcAdapter.lambda$deferOnce$23(OracleReactiveJdbcAdapter.java:1070) ~[oracle-r2dbc-0.1.0.jar:0.1.0]
    	at oracle.r2dbc.impl.OracleReactiveJdbcAdapter$$Lambda$595/0000000039BC68E0.subscribe(Unknown Source) ~[na:na]
    	at reactor.core.publisher.FluxSource.subscribe(FluxSource.java:66) ~[reactor-core-3.4.4.jar:3.4.4]
    	at reactor.core.publisher.Mono.subscribe(Mono.java:4099) ~[reactor-core-3.4.4.jar:3.4.4]
    	at reactor.core.publisher.FluxConcatArray$ConcatArraySubscriber.onComplete(FluxConcatArray.java:208) ~[reactor-core-3.4.4.jar:3.4.4]
    	at reactor.core.publisher.FluxConcatArray.subscribe(FluxConcatArray.java:80) ~[reactor-core-3.4.4.jar:3.4.4]
    	at reactor.core.publisher.Flux.subscribe(Flux.java:8185) ~[reactor-core-3.4.4.jar:3.4.4]
    	at reactor.core.publisher.Flux.subscribeWith(Flux.java:8358) ~[reactor-core-3.4.4.jar:3.4.4]
    	at reactor.core.publisher.Flux.subscribe(Flux.java:8155) ~[reactor-core-3.4.4.jar:3.4.4]
    	at reactor.core.publisher.Flux.subscribe(Flux.java:8079) ~[reactor-core-3.4.4.jar:3.4.4]
    	at reactor.pool.SimpleDequePool.drainLoop(SimpleDequePool.java:404) ~[reactor-pool-0.2.3.jar:0.2.3]
    	at reactor.pool.SimpleDequePool.pendingOffer(SimpleDequePool.java:521) ~[reactor-pool-0.2.3.jar:0.2.3]
    	at reactor.pool.SimpleDequePool.doAcquire(SimpleDequePool.java:254) ~[reactor-pool-0.2.3.jar:0.2.3]
    	at reactor.pool.AbstractPool$Borrower.request(AbstractPool.java:382) ~[reactor-pool-0.2.3.jar:0.2.3]
    	at reactor.core.publisher.FluxPeek$PeekSubscriber.request(FluxPeek.java:137) ~[reactor-core-3.4.4.jar:3.4.4]
    	at org.springframework.cloud.sleuth.instrument.reactor.ScopePassingSpanSubscriber.request(ScopePassingSpanSubscriber.java:74) ~[spring-cloud-sleuth-instrumentation-3.0.0.jar:3.0.0]
    	at reactor.core.publisher.FluxPeek$PeekSubscriber.request(FluxPeek.java:137) ~[reactor-core-3.4.4.jar:3.4.4]
    	at org.springframework.cloud.sleuth.instrument.reactor.ScopePassingSpanSubscriber.request(ScopePassingSpanSubscriber.java:74) ~[spring-cloud-sleuth-instrumentation-3.0.0.jar:3.0.0]
    	at reactor.core.publisher.MonoFlatMap$FlatMapMain.onSubscribe(MonoFlatMap.java:110) ~[reactor-core-3.4.4.jar:3.4.4]
    	at org.springframework.cloud.sleuth.instrument.reactor.ScopePassingSpanSubscriber.onSubscribe(ScopePassingSpanSubscriber.java:67) ~[spring-cloud-sleuth-instrumentation-3.0.0.jar:3.0.0]
    	at reactor.core.publisher.FluxPeek$PeekSubscriber.onSubscribe(FluxPeek.java:170) ~[reactor-core-3.4.4.jar:3.4.4]
    	at org.springframework.cloud.sleuth.instrument.reactor.ScopePassingSpanSubscriber.onSubscribe(ScopePassingSpanSubscriber.java:67) ~[spring-cloud-sleuth-instrumentation-3.0.0.jar:3.0.0]
    	at reactor.core.publisher.FluxPeek$PeekSubscriber.onSubscribe(FluxPeek.java:170) ~[reactor-core-3.4.4.jar:3.4.4]
    	at reactor.pool.SimpleDequePool$QueueBorrowerMono.subscribe(SimpleDequePool.java:632) ~[reactor-pool-0.2.3.jar:0.2.3]
    	at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.4.4.jar:3.4.4]
    	at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) ~[reactor-core-3.4.4.jar:3.4.4]
    	at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.4.4.jar:3.4.4]
    	at reactor.core.publisher.FluxRetry$RetrySubscriber.resubscribe(FluxRetry.java:116) ~[reactor-core-3.4.4.jar:3.4.4]
    	at reactor.core.publisher.MonoRetry.subscribeOrReturn(MonoRetry.java:49) ~[reactor-core-3.4.4.jar:3.4.4]
    	at reactor.core.publisher.Mono.subscribe(Mono.java:4084) ~[reactor-core-3.4.4.jar:3.4.4]
    	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:103) ~[reactor-core-3.4.4.jar:3.4.4]
    	at org.springframework.cloud.sleuth.instrument.reactor.ScopePassingSpanSubscriber.onError(ScopePassingSpanSubscriber.java:95) ~[spring-cloud-sleuth-instrumentation-3.0.0.jar:3.0.0]
    	at reactor.core.publisher.MonoFlatMap$FlatMapMain.onError(MonoFlatMap.java:172) ~[reactor-core-3.4.4.jar:3.4.4]
    	at org.springframework.cloud.sleuth.instrument.reactor.ScopePassingSpanSubscriber.onError(ScopePassingSpanSubscriber.java:95) ~[spring-cloud-sleuth-instrumentation-3.0.0.jar:3.0.0]
    	at reactor.core.publisher.FluxMap$MapSubscriber.onError(FluxMap.java:132) ~[reactor-core-3.4.4.jar:3.4.4]
    	at org.springframework.cloud.sleuth.instrument.reactor.ScopePassingSpanSubscriber.onError(ScopePassingSpanSubscriber.java:95) ~[spring-cloud-sleuth-instrumentation-3.0.0.jar:3.0.0]
    	at reactor.core.publisher.Operators.error(Operators.java:197) ~[reactor-core-3.4.4.jar:3.4.4]
    	at reactor.core.publisher.MonoError.subscribe(MonoError.java:52) ~[reactor-core-3.4.4.jar:3.4.4]
    	at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) ~[reactor-core-3.4.4.jar:3.4.4]
    	at reactor.core.publisher.MonoDeferContextual.subscribe(MonoDeferContextual.java:55) ~[reactor-core-3.4.4.jar:3.4.4]
    	at reactor.core.publisher.Mono.subscribe(Mono.java:4099) ~[reactor-core-3.4.4.jar:3.4.4]
    	at reactor.core.publisher.FluxUsingWhen.subscribe(FluxUsingWhen.java:103) ~[reactor-core-3.4.4.jar:3.4.4]
    	at reactor.core.publisher.Mono.subscribe(Mono.java:4099) ~[reactor-core-3.4.4.jar:3.4.4]
    	at kotlinx.coroutines.reactive.AwaitKt.awaitOne(Await.kt:137) ~[kotlinx-coroutines-reactive-1.4.3.jar:na]
    	at kotlinx.coroutines.reactive.AwaitKt.awaitOne$default(Await.kt:135) ~[kotlinx-coroutines-reactive-1.4.3.jar:na]
    	at kotlinx.coroutines.reactive.AwaitKt.awaitFirst(Await.kt:26) ~[kotlinx-coroutines-reactive-1.4.3.jar:na]
    

    Without the connection pool, everything runs fine, but with a low throughput. Am I missing any configuration or is this a known limitation?

    opened by dpavanelli 32
  • LDAP URI it does not work

    LDAP URI it does not work

    oracle-r2dbc version: 0.2.0 spring-boot: 2.5.2 Database: Oracle 19c

    r2dbc:oracle:thin:@ldap://server:port/database,cn=OracleContext,dc=WORLD

    Error:

    reactor.core.Exceptions$ErrorCallbackNotImplemented: io.r2dbc.spi.R2dbcTransientResourceException: [17002] [08006] Error de E/S: Invalid connection string format, a valid format is: "host:port:sid" (CONNECTION_ID=qyq8AuNhQreSmex/HBjgiA==) Caused by: io.r2dbc.spi.R2dbcTransientResourceException: Error de E/S: Invalid connection string format, a valid format is: "host:port:sid" (CONNECTION_ID=qyq8AuNhQreSmex/HBjgiA==) at oracle.r2dbc.impl.OracleR2dbcExceptions.toR2dbcException(OracleR2dbcExceptions.java:211) at oracle.r2dbc.impl.OracleReactiveJdbcAdapter$$Lambda$1262/00000000A3888C30.apply(Unknown Source) at reactor.core.publisher.Flux.lambda$onErrorMap$29(Flux.java:6720) at reactor.core.publisher.Flux$$Lambda$1264/000000008D4CE270.apply(Unknown Source)

    code for test:

    		ConnectionFactory connectionFactory = ConnectionFactories.get(
    				"r2dbc:oracle:thin:@ldap://server:port/database,cn=OracleContext,dc=WORLD");
    
    		Mono.from(connectionFactory.create())
    				.flatMapMany(connection ->
    						Flux.from(connection.createStatement(
    								"SELECT 'Hello, Oracle' FROM sys.dual")
    								.execute())
    								.flatMap(result ->
    										result.map((row, metadata) -> row.get(0, String.class)))
    								.doOnNext(System.out::println)
    								.thenMany(connection.close()))
    				.subscribe();
    

    thanks

    opened by raenjamio 22
  • Memory Leak Suspect in ForwardOnlyResultSet

    Memory Leak Suspect in ForwardOnlyResultSet

    Hi, i am so glad to be using this wonderful reactive driver for Oracle!
    Thanks

    Application

    • Java Version: 17.0.2 openjdk
    • oracle-r2dbc Version: 1.0.0
    • r2dbc-pool Version: 0.9.1
    • ojdbc Version: ojdbc11:21.3.0.0

    Description

    I have in production an application which, servers a lot of data, and, have many hits per second.
    Basically, it uses cache-aside technique with redis.
    So, go redis, key not in redis, go to oracle, do some mappings, store it into redis.

    It works like a charm, but, when the application is running on a day without interruption, on our apm, I start to see a memory consumption growth, and the garbage collector can not clean the memory and, the memory average starts to growth, and growth and growth.

    I took a heap dump, and, with eclipse memory analyzer I saw that, the heap has a lot of ForwardOnlyResultSet objects, which, it seems that its not closed after the use.

    Here, we can see that we have a lot of instances of ForwardOnlyResultSet image

    Since, we are using r2dbc-pool, with a pool of 5 connections,
    image

    I might be missing something, and forgetting to close the result set. Which, is something that I would to on pure jdbc. But, I havent seen nothing here in the docs about that.

    Example of use

    I suspect that I am not closing the result set below, I am just closing(returning the connection back to the pool) after each statement

        public Mono<CouponDto> fetchCoupon(final long itemId, final long couponId, final long subsidiaryId) {
            return Flux.usingWhen(
                    connectionPool.create(),
                    connection -> Mono.from(connection.createStatement(QUERY)
                            .bind(0, subsidiaryId)
                            .bind(1, itemId)
                            .bind(2, couponId)
                            .execute()
                    ).flatMapMany(it -> it.map(mapper)),
                    Connection::close,
                    ((connection, throwable) -> connection.close()),
                    Connection::close
            ).next();
        }
    
        private final BiFunction<Row, RowMetadata, CouponDto> mapper = (row, rowMetadata) ->
                new CouponDto(
                        row.get("id", Long.class),
                        row.get("discountPercentage", Double.class),
                        row.get("listPrice", Double.class),
                        row.get("discountType", Integer.class)
                );
    
    

    Again, thanks for your help & time! Best Regards, Matheus Rambo

    opened by sgtcortez 15
  • r2dbc pool support

    r2dbc pool support

    When trying to use with spring-boot-starter-data-r2dbc and enabled pool I get the following exception

    2021-06-16 23:08:35,144 [RMI TCP Connection(2)-100.64.118.0] DEBUG org.springframework.core.env.PropertySourcesPropertyResolver [logKeyFound] [RMI TCP Connection(2)-100.64.118.0] [] : Found key 'local.server.port' in PropertySource 'server.ports' with value of type Integer
    2021-06-16 23:08:35,377 [RMI TCP Connection(3)-100.64.118.0] DEBUG reactor.util.Loggers$Slf4JLogger [debug] [RMI TCP Connection(3)-100.64.118.0] [] : Obtaining new connection from the driver
    2021-06-16 23:08:35,379 [RMI TCP Connection(3)-100.64.118.0] DEBUG reactor.util.Loggers$Slf4JLogger [debug] [RMI TCP Connection(3)-100.64.118.0] [] : should warm up 4 extra resources
    2021-06-16 23:08:37,571 [ForkJoinPool.commonPool-worker-3] DEBUG reactor.util.Loggers$Slf4JLogger [debug] [ForkJoinPool.commonPool-worker-3] [] : Duplicate Subscription has been detected
    java.lang.IllegalStateException: Spec. Rule 2.12 - Subscriber.onSubscribe MUST NOT be called more than once (based on object equality)
    	at reactor.core.Exceptions.duplicateOnSubscribeException(Exceptions.java:180)
    	at reactor.core.publisher.Operators.reportSubscriptionSet(Operators.java:1083)
    	at reactor.core.publisher.Operators.setOnce(Operators.java:1188)
    	at reactor.core.publisher.MonoFlatMap$FlatMapInner.onSubscribe(MonoFlatMap.java:237)
    	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onSubscribe(FluxOnErrorResume.java:72)
    	at reactor.core.publisher.Operators.reportThrowInSubscribe(Operators.java:225)
    	at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:71)
    	at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:157)
    	at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:199)
    	at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:199)
    	at reactor.pool.AbstractPool$Borrower.deliver(AbstractPool.java:410)
    	at reactor.pool.SimpleDequePool.lambda$drainLoop$7(SimpleDequePool.java:382)
    	at reactor.core.publisher.FluxDoOnEach$DoOnEachSubscriber.onNext(FluxDoOnEach.java:154)
    	at reactor.core.publisher.FluxMap$MapConditionalSubscriber.onNext(FluxMap.java:220)
    	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79)
    	at reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:82)
    	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79)
    	at org.reactivestreams.FlowAdapters$FlowToReactiveSubscriber.onNext(FlowAdapters.java:218)
    	at oracle.jdbc.datasource.impl.OracleDataSource$ConnectionPublisher$ConnectionSubscription.emitConnection(OracleDataSource.java:2746)
    	at oracle.jdbc.datasource.impl.OracleDataSource$ConnectionPublisher$ConnectionSubscription.lambda$publishConnectionAsync$0(OracleDataSource.java:2733)
    	at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:859)
    	at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:837)
    	at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:506)
    	at java.base/java.util.concurrent.CompletableFuture.postFire(CompletableFuture.java:610)
    	at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:840)
    	at java.base/java.util.concurrent.CompletableFuture$Completion.run(CompletableFuture.java:478)
    	at oracle.jdbc.driver.PhysicalConnection.lambda$createUserCodeExecutor$10(PhysicalConnection.java:11713)
    	at java.base/java.security.AccessController.doPrivileged(Native Method)
    	at oracle.jdbc.driver.PhysicalConnection.lambda$createUserCodeExecutor$11(PhysicalConnection.java:11711)
    	at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1426)
    	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
    	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
    	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
    	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
    	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:177)
    

    my pool configuration

    spring:
      r2dbc:
        username: ....
        password: ....
        url: r2dbc:...
        pool:
          initial-size: 5
          max-idle-time: 10m
          max-size: 30
          enabled: true
      data:
        r2dbc:
          repositories:
            enabled: true
    

    Is working with pool currently supported?

    opened by sashuki 12
  • Regressions comparing with 0.1

    Regressions comparing with 0.1

    I'm hitting a lot of errors trying to upgrade the dependency to 0.2 in Micronaut R2dbc integration

    • We used to generate the boolean representation as NUMBER(3) and it used to work, now it fails because every boolean is expected to be BOOLEAN type which we don't have in version 18, the only one available officially at https://hub.docker.com/r/gvenzl/oracle-xe
    • It looks like byte[] type is not supported anymore and ByteBuffer is the only one supported
    opened by dstepanov 10
  • Support for connect descriptors

    Support for connect descriptors

    Hi,

    I can't find a way to set the connect descriptor in the URL like recommended here: https://docs.oracle.com/database/121/HABPT/config_fcf.htm#HABPT4967

    Am I missing something or is this not supported?

    opened by razum90 10
  • Class Cast Exceptio when I call subscribe method on a Mono

    Class Cast Exceptio when I call subscribe method on a Mono

    Sample Code:

    Exception takes place in the highlighted code in bold below

    testSubscriptionMono.flatMap(testSubscription -> { testSubscription.setMembershipStatus("ENROLLED"); return repositoryService.saveTestSubscription(testSubscription); }).subscribe(value -> System.out.println("RECEIVED " + value), error -> error.printStackTrace());

    Depdendencies:

    image

    Error Logs:

    java.lang.ClassCastException: class java.lang.Long cannot be cast to class java.lang.Integer (java.lang.Long and java.lang.Integer are in module java.base of loader 'bootstrap') at java.base/java.util.stream.Collectors.lambda$summingInt$19(Collectors.java:673) at reactor.core.publisher.MonoStreamCollector$StreamCollectorSubscriber.onNext(MonoStreamCollector.java:132) at reactor.core.publisher.FluxFlatMap$FlatMapMain.tryEmit(FluxFlatMap.java:543) at reactor.core.publisher.FluxFlatMap$FlatMapInner.onNext(FluxFlatMap.java:984) at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:200) at reactor.core.publisher.FluxConcatArray$ConcatArrayDelayErrorSubscriber.onNext(FluxConcatArray.java:364) at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.onNext(FluxFilterFuseable.java:118) at reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onNext(FluxMapFuseable.java:299) at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2398) at reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.request(FluxMapFuseable.java:360) at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.request(FluxFilterFuseable.java:191) at reactor.core.publisher.FluxConcatArray$ConcatArrayDelayErrorSubscriber.request(FluxConcatArray.java:461) at reactor.core.publisher.FluxPeek$PeekSubscriber.request(FluxPeek.java:138) at reactor.core.publisher.FluxFlatMap$FlatMapInner.onSubscribe(FluxFlatMap.java:964) at reactor.core.publisher.FluxPeek$PeekSubscriber.onSubscribe(FluxPeek.java:171) at reactor.core.publisher.FluxConcatArray$ConcatArrayDelayErrorSubscriber.onSubscribe(FluxConcatArray.java:350) at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.onSubscribe(FluxFilterFuseable.java:87) at reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onSubscribe(FluxMapFuseable.java:265) at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:55) at reactor.core.publisher.Flux.subscribe(Flux.java:8466) at reactor.core.publisher.FluxConcatArray$ConcatArrayDelayErrorSubscriber.onComplete(FluxConcatArray.java:443) at reactor.core.publisher.FluxConcatArray.subscribe(FluxConcatArray.java:73) at reactor.core.publisher.Flux.subscribe(Flux.java:8466) at reactor.core.publisher.FluxFlatMap$FlatMapMain.onNext(FluxFlatMap.java:426) at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onNext(FluxOnAssembly.java:539) at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:122) at reactor.core.publisher.MonoFlatMapMany$FlatMapManyInner.onNext(MonoFlatMapMany.java:250) at reactor.core.publisher.FluxUsingWhen$UsingWhenSubscriber.onNext(FluxUsingWhen.java:345) at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79) at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:200) at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:122) at reactor.core.publisher.FluxConcatArray$ConcatArraySubscriber.onNext(FluxConcatArray.java:201) at reactor.core.publisher.MonoFlatMapMany$FlatMapManyInner.onNext(MonoFlatMapMany.java:250) at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2398) at reactor.core.publisher.MonoFlatMapMany$FlatMapManyMain.onSubscribeInner(MonoFlatMapMany.java:150) at reactor.core.publisher.MonoFlatMapMany$FlatMapManyMain.onNext(MonoFlatMapMany.java:189) at reactor.core.publisher.MonoCreate$DefaultMonoSink.success(MonoCreate.java:172) at oracle.r2dbc.impl.AsyncLock.lambda$get$2(AsyncLock.java:167) at oracle.r2dbc.impl.AsyncLock.unlock(AsyncLock.java:125) at oracle.r2dbc.impl.AsyncLock$UsingConnectionSubscriber.terminate(AsyncLock.java:516) at oracle.r2dbc.impl.AsyncLock$UsingConnectionSubscriber.onComplete(AsyncLock.java:502) at reactor.core.publisher.StrictSubscriber.onComplete(StrictSubscriber.java:123) at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onComplete(Operators.java:2058) at org.reactivestreams.FlowAdapters$FlowToReactiveSubscriber.onComplete(FlowAdapters.java:221) at oracle.jdbc.internal.CompletionStageUtil$IteratorSubscription.emitComplete(CompletionStageUtil.java:805) at oracle.jdbc.internal.CompletionStageUtil$IteratorSubscription.emitItems(CompletionStageUtil.java:752) at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1426) at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290) at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020) at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656) at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594) at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)

    opened by karthickbhaskar 9
  • Cannot change password of connection factory after creation

    Cannot change password of connection factory after creation

    I'm using this driver in a r2dbc connection pool which is meant to have variable size. The password for the database I'm accessing rotates hourly... I was hoping to extend the classes

    https://github.com/oracle/oracle-r2dbc/blob/main/src/main/java/oracle/r2dbc/impl/OracleConnectionFactoryImpl.java https://github.com/oracle/oracle-r2dbc/blob/main/src/main/java/oracle/r2dbc/impl/OracleReactiveJdbcAdapter.java

    to use an extended version of OracleDataSource where the getConnection() functions can call out to retrieve updated passwords.

    However, it seems nearly everything in this lib is a final or protected class and cannot be extended...

    Is there a better solution to this? Do I have to just destroy my connection pool every time it fails to create a new connection and recreate it entirely?

    Would it be possible to make these classes public and non-final? Or even allow a supplier like Mono<String> for the password?

    opened by calebcodesgud 9
  • NullPointer when using R2DBC Pool 0.9.0.RELEASE with version 0.4.0

    NullPointer when using R2DBC Pool 0.9.0.RELEASE with version 0.4.0

    Hi, I am facing a weird problem using:

    Java Version: Oracle JDK 17

    implementation 'io.r2dbc:r2dbc-pool:0.9.0.RELEASE'
    implementation 'io.r2dbc:r2dbc-spi:0.9.0.RELEASE'
    runtimeOnly 'com.oracle.database.r2dbc:oracle-r2dbc:0.4.0'
    

    First of all, I was using the version 0.1.0 with R2DBC POOL, and, it works when executing a single statement, but, with paralell calls, I face the problem with: Multiple subscribers ...

    So, I came here, and, read that thats a know problem with version 0.1.0. Then, I upgrade to the version 0.4.0 which, is the latest.
    But, trying to execute the same query(which works with version 0.1.0) , but, I am receiving a NullPointer inside oracle r2dbc classes.

    StackTrace:

    java.lang.NullPointerException: Cannot invoke "java.util.ArrayDeque.size()" because "this.implicitResultSetStatements" is null
    	at oracle.jdbc.driver.OracleStatement.getMoreResults(OracleStatement.java:5851)
    	at oracle.jdbc.driver.OracleStatementWrapper.getMoreResults(OracleStatementWrapper.java:298)
    	at oracle.r2dbc.impl.OracleStatementImpl$JdbcStatement.lambda$getResults$4(OracleStatementImpl.java:1053)
    	at oracle.r2dbc.impl.AsyncLock.lambda$get$2(AsyncLock.java:161)
    	at oracle.r2dbc.impl.AsyncLock.unlock(AsyncLock.java:122)
    	at oracle.r2dbc.impl.AsyncLock$UsingConnectionSubscriber.terminate(AsyncLock.java:510)
    	at oracle.r2dbc.impl.AsyncLock$UsingConnectionSubscriber.onComplete(AsyncLock.java:496)
    	at reactor.core.publisher.StrictSubscriber.onComplete(StrictSubscriber.java:123)
    	at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onComplete(Operators.java:2058)
    	at org.reactivestreams.FlowAdapters$FlowToReactiveSubscriber.onComplete(FlowAdapters.java:228)
    	at oracle.jdbc.internal.CompletionStageUtil$IteratorSubscription.emitComplete(CompletionStageUtil.java:681)
    	at oracle.jdbc.internal.CompletionStageUtil$IteratorSubscription.emitItems(CompletionStageUtil.java:628)
    	at oracle.jdbc.driver.PhysicalConnection.lambda$createUserCodeExecutor$10(PhysicalConnection.java:11713)
    	at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    	at oracle.jdbc.driver.PhysicalConnection.lambda$createUserCodeExecutor$11(PhysicalConnection.java:11711)
    	at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1395)
    	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)
    	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182)
    	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655)
    	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622)
    	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165)
    

    How I execute the query:

    return Mono.usingWhen(
            connectionPool.create(),
            connection -> Mono.from(connection.createStatement(QUERY)
                    .bind(0, destinationState)
                    .bind(1, subsidiaryId)
                    .bind(2, itemId)
                    .execute()
            ),
            Connection::close,
            ((connection, throwable) -> connection.close()),
            Connection::close
    )
            .flatMapMany(it -> it.map(mapper))
            .next();
    

    How I create the connection pool:

    public ConnectionPool connectionFactory() {
        return new ConnectionPool(ConnectionPoolConfiguration
                .builder()
                .connectionFactory(ConnectionFactories.get(
                        ConnectionFactoryOptions
                                .builder()
                                .from(ConnectionFactoryOptions.parse(url))
                                .option(ConnectionFactoryOptions.USER, user)
                                .option(ConnectionFactoryOptions.PASSWORD, password)
                                .option(ConnectionFactoryOptions.DRIVER, DRIVER)
                                .option(Option.valueOf("applicationName"), "catalog-service-app")
                                .build()
                        )
                )
                .initialSize(INITIAL_CONNECTIONS)
                .maxSize(maxConnections)
                .maxIdleTime(Duration.ofSeconds(maxIdleTime))
                .validationQuery(VALIDATION_QUERY)
                .build()
        );
    }
    

    I thought that I would be a problem with dependency versions, but, I checked the dependencies and, I am using the correct ones.
    Please, tell me where I am making a mistake

    Dependencies:
    image

    opened by sgtcortez 9
  • R2DBC treating warning as exception

    R2DBC treating warning as exception

    Hi,

    I am using R2DBC with oracle, where I am trying to get some details from a view. This view is having some warning while executing it which is not an exception but R2DBC is treating that as exception and is failing.

    If I run the exact same query with limit of 9 or less records it works fine. I tried this view with Spring data JPA and there it works perfectly fine.

    Database used in this case is Oracle

    Please have a look on this below log for more details.

    2022-09-09 15:03:51,876 INFO  [reactor-http-nio-2] com.gic.eagle.txnHld.handler.VWODAHoldingEglHandler: trying to get view data from ODA RE from [01Jan1991] to [09Jan2022]
    2022-09-09 15:04:09,993 DEBUG [ForkJoinPool.commonPool-worker-3] org.springframework.r2dbc.core.DefaultDatabaseClient$DefaultGenericExecuteSpec: Executing SQL statement [SELECT * from <View_Name> WHERE DATA_DT >= :P0_startDate AND DATA_DT <=:P1_endDate]
    2022-09-09 15:04:10,384 ERROR [ForkJoinPool.commonPool-worker-3] reactor.util.Loggers$Slf4JLogger: Operator called default onErrorDropped
    reactor.core.Exceptions$StaticThrowable: Operator has been terminated
    2022-09-09 15:04:10,411 ERROR [ForkJoinPool.commonPool-worker-3] com.gic.eagle.txnHld.handler.TxnHldDataTransHandler: Error [executeMany; SQL [SELECT * from <View_Name> WHERE DATA_DT >= :P0_startDate AND DATA_DT <=:P1_endDate]; Warning: execution completed with warning; nested exception is oracle.r2dbc.impl.OracleR2dbcExceptions$OracleR2dbcException: [17110] [99999] Warning: execution completed with warning]
    org.springframework.r2dbc.UncategorizedR2dbcException: executeMany; SQL [SELECT * from <View_Name> WHERE DATA_DT >= :P0_startDate AND DATA_DT <=:P1_endDate]; Warning: execution completed with warning; nested exception is oracle.r2dbc.impl.OracleR2dbcExceptions$OracleR2dbcException: [17110] [99999] Warning: execution completed with warning
    	at org.springframework.r2dbc.connection.ConnectionFactoryUtils.convertR2dbcException(ConnectionFactoryUtils.java:238)
    	at org.springframework.r2dbc.core.DefaultDatabaseClient.lambda$inConnectionMany$8(DefaultDatabaseClient.java:147)
    	at reactor.core.publisher.Flux.lambda$onErrorMap$29(Flux.java:6943)
    	at reactor.core.publisher.Flux.lambda$onErrorResume$30(Flux.java:6996)
    	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:94)
    	at reactor.core.publisher.FluxUsingWhen$UsingWhenSubscriber.deferredError(FluxUsingWhen.java:398)
    	at reactor.core.publisher.FluxUsingWhen$RollbackInner.onComplete(FluxUsingWhen.java:475)
    	at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onComplete(Operators.java:2058)
    	at reactor.core.publisher.MonoNext$NextSubscriber.onComplete(MonoNext.java:102)
    	at reactor.core.publisher.MonoNext$NextSubscriber.onComplete(MonoNext.java:102)
    	at oracle.r2dbc.impl.AsyncLock$UsingConnectionSubscriber.onComplete(AsyncLock.java:497)
    	at reactor.core.publisher.StrictSubscriber.onComplete(StrictSubscriber.java:123)
    	at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onComplete(Operators.java:2058)
    	at org.reactivestreams.FlowAdapters$FlowToReactiveSubscriber.onComplete(FlowAdapters.java:221)
    	at oracle.jdbc.internal.CompletionStageUtil$IteratorSubscription.emitComplete(CompletionStageUtil.java:805)
    	at oracle.jdbc.internal.CompletionStageUtil$BatchItemPublisher.subscribeToBatch(CompletionStageUtil.java:622)
    	at oracle.jdbc.internal.CompletionStageUtil$BatchItemPublisher.lambda$subscribe$0(CompletionStageUtil.java:593)
    	at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:859)
    	at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:837)
    	at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:506)
    	at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2073)
    	at oracle.jdbc.driver.T4CTTIfun.lambda$doRPCAsync$0(T4CTTIfun.java:348)
    	at oracle.jdbc.driver.T4CTTIfun.lambda$receiveRPCAsync$1(T4CTTIfun.java:474)
    	at oracle.jdbc.driver.RestrictedLock.lambda$runUnrestricted$0(RestrictedLock.java:428)
    	at oracle.jdbc.driver.RestrictedLock.callUnrestricted(RestrictedLock.java:447)
    	at oracle.jdbc.driver.RestrictedLock.runUnrestricted(RestrictedLock.java:427)
    	at oracle.jdbc.driver.PhysicalConnection.lambda$initializeAsyncExecutor$4(PhysicalConnection.java:1270)
    	at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1426)
    	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
    	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
    	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
    	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
    	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)
    Caused by: oracle.r2dbc.impl.OracleR2dbcExceptions$OracleR2dbcException: Warning: execution completed with warning
    	at oracle.r2dbc.impl.OracleR2dbcExceptions.toR2dbcException(OracleR2dbcExceptions.java:217)
    	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
    	at java.base/java.util.stream.Stream$2.tryAdvance(Stream.java:1301)
    	at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.lambda$initPartialTraversalState$0(StreamSpliterators.java:294)
    	at java.base/java.util.stream.StreamSpliterators$AbstractWrappingSpliterator.fillBuffer(StreamSpliterators.java:206)
    	at java.base/java.util.stream.StreamSpliterators$AbstractWrappingSpliterator.doAdvance(StreamSpliterators.java:161)
    	at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.tryAdvance(StreamSpliterators.java:300)
    	at java.base/java.util.Spliterators$1Adapter.hasNext(Spliterators.java:681)
    	at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:133)
    Caused by: oracle.r2dbc.impl.OracleR2dbcExceptions$OracleR2dbcException: Warning: execution completed with warning
    
    	at reactor.core.publisher.FluxStream.subscribe(FluxStream.java:71)
    	at reactor.core.publisher.Flux.subscribe(Flux.java:8466)
    	at reactor.core.publisher.FluxConcatArray$ConcatArraySubscriber.onComplete(FluxConcatArray.java:258)
    	at reactor.core.publisher.FluxConcatArray.subscribe(FluxConcatArray.java:78)
    	at reactor.core.publisher.Flux.subscribe(Flux.java:8466)
    	at reactor.core.publisher.FluxConcatArray$ConcatArrayDelayErrorSubscriber.onComplete(FluxConcatArray.java:443)
    	at reactor.core.publisher.FluxConcatArray.subscribe(FluxConcatArray.java:73)
    	at reactor.core.publisher.InternalFluxOperator.subscribe(InternalFluxOperator.java:62)
    	at reactor.core.publisher.FluxDefer.subscribe(FluxDefer.java:54)
    	at reactor.core.publisher.Flux.subscribe(Flux.java:8466)
    	at reactor.core.publisher.FluxFlatMap$FlatMapMain.onNext(FluxFlatMap.java:426)
    	at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onNext(FluxOnAssembly.java:539)
    	at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:122)
    	at reactor.core.publisher.MonoFlatMapMany$FlatMapManyInner.onNext(MonoFlatMapMany.java:250)
    	at reactor.core.publisher.FluxUsingWhen$UsingWhenSubscriber.onNext(FluxUsingWhen.java:345)
    	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79)
    	at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:200)
    	at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:122)
    	at reactor.core.publisher.FluxConcatArray$ConcatArraySubscriber.onNext(FluxConcatArray.java:201)
    	at reactor.core.publisher.MonoFlatMapMany$FlatMapManyInner.onNext(MonoFlatMapMany.java:250)
    	at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2398)
    	at reactor.core.publisher.MonoFlatMapMany$FlatMapManyMain.onSubscribeInner(MonoFlatMapMany.java:150)
    	at reactor.core.publisher.MonoFlatMapMany$FlatMapManyMain.onNext(MonoFlatMapMany.java:189)
    	at reactor.core.publisher.MonoCreate$DefaultMonoSink.success(MonoCreate.java:172)
    	at oracle.r2dbc.impl.AsyncLock.lambda$get$2(AsyncLock.java:163)
    	at oracle.r2dbc.impl.AsyncLock.unlock(AsyncLock.java:122)
    	at oracle.r2dbc.impl.AsyncLock$UsingConnectionSubscriber.terminate(AsyncLock.java:510)
    	at oracle.r2dbc.impl.AsyncLock$UsingConnectionSubscriber.onComplete(AsyncLock.java:496)
    	at reactor.core.publisher.StrictSubscriber.onComplete(StrictSubscriber.java:123)
    	at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onComplete(Operators.java:2058)
    	at org.reactivestreams.FlowAdapters$FlowToReactiveSubscriber.onComplete(FlowAdapters.java:221)
    	at oracle.jdbc.internal.CompletionStageUtil$IteratorSubscription.emitComplete(CompletionStageUtil.java:805)
    	at oracle.jdbc.internal.CompletionStageUtil$IteratorSubscription.emitItems(CompletionStageUtil.java:752)
    	... 6 common frames omitted
    Caused by: java.sql.SQLWarning: Warning: execution completed with warning
    	at oracle.jdbc.driver.DatabaseError.addSqlWarning(DatabaseError.java:1078)
    Caused by: java.sql.SQLWarning: Warning: execution completed with warning
    
    	at oracle.jdbc.driver.DatabaseError.addSqlWarning(DatabaseError.java:1122)
    	at oracle.jdbc.driver.DatabaseError.addSqlWarning(DatabaseError.java:1135)
    	at oracle.jdbc.driver.T4CPreparedStatement.handleOALL8Failure(T4CPreparedStatement.java:478)
    	at oracle.jdbc.driver.T4CPreparedStatement.lambda$doOall8Async$0(T4CPreparedStatement.java:221)
    	at oracle.jdbc.driver.T4C8Oall.lambda$doOALLAsync$0(T4C8Oall.java:583)
    	at oracle.jdbc.driver.T4CTTIfun.lambda$receiveRPCAsync$1(T4CTTIfun.java:474)
    	at oracle.jdbc.driver.RestrictedLock.lambda$runUnrestricted$0(RestrictedLock.java:428)
    	at oracle.jdbc.driver.RestrictedLock.callUnrestricted(RestrictedLock.java:447)
    	at oracle.jdbc.driver.RestrictedLock.runUnrestricted(RestrictedLock.java:427)
    	at oracle.jdbc.driver.PhysicalConnection.lambda$initializeAsyncExecutor$4(PhysicalConnection.java:1270)
    	... 6 common frames omitted
    2022-09-09 15:17:17,034 INFO  [reactor-http-nio-3] com.gic.eagle.txnHld.handler.VWODAHoldingEglHandler: trying to get 
    

    Originally raised on https://github.com/spring-projects/spring-data-r2dbc/issues/784

    opened by rathoreamrsingh 8
  • Is Oracle support back ?

    Is Oracle support back ?

    Hi, It has been unclear if there is Oracle database support for spring r2dbc. Is it active after Oracles odbc extention api? When is the first lease planned ?

    opened by mehmetekici 8
  • Issue with the OracleR2dbcOptions.Executor option

    Issue with the OracleR2dbcOptions.Executor option

    We are facing some issues with the Executor option set to default in our containerized app which has 2 cpu cores. All the DB calls in our app hang after approx. 10 mins of load test. There is no log to indicate what's gone wrong. We do not have the means yet to pull a thread dump. The cpu and memory usage is normal and the connections in the pool are well within the limit. This issue occurs when: a) The OracleR2dbcIptions.EXECUTOR is not set, left to be default OR b) Set to Executors.newWorkStealingPool(2)

    When we set this option to "new ForkJoinPool(4)", our load tests seem to run fine. The one thing that I noticed with this option is that the asyncMode for the ForkJoinPool is set to false.

    opened by htejwani 1
  • Sample Bug: r2dbc version

    Sample Bug: r2dbc version

    The sample <oracle-r2dbc.version>0.3.0</oracle-r2dbc.version> produces an error with missing symbol for DescriptorUrl.

    This can be fixed by upgrading to <oracle-r2dbc.version>1.0.0</oracle-r2dbc.version>

    opened by naberin 0
  • Upgrade from oracle-r2dbc version 0.4.0 to 1.0.0 is resulting in class cast exception while update.

    Upgrade from oracle-r2dbc version 0.4.0 to 1.0.0 is resulting in class cast exception while update.

    Hi,

    I was trying to upgrade R2DBC from 0.4.0 to 1.0.0. while doing that I am getting error in update which was working fine in version 0.4.0.

    Below is the SQL Update Query from R2dbcRepository Repository:

    @Modifying
      @Query(value = "UPDATE <Table_name> SET PARAM_VALUE=:paramValue WHERE BATCH_ID=:batchId and PARAM_NAME=:paramName")
      Mono<Integer> updateODADateParam(String paramValue, String batchId, String paramName);
    

    Error Log:

    2022-10-05 09:47:37,080 DEBUG [ForkJoinPool.commonPool-worker-3] org.springframework.r2dbc.core.DefaultDatabaseClient$DefaultGenericExecuteSpec: Executing SQL statement [UPDATE <table_name> SET PARAM_VALUE=:P0_paramValue WHERE BATCH_ID=:P1_batchId and PARAM_NAME=:P2_paramName]
    2022-10-05 09:47:37,121 ERROR [ForkJoinPool.commonPool-worker-7] com.gic.eagle.txnHld.handler.RESIBatchDateHandler: Error [class java.lang.Long cannot be cast to class java.lang.Integer (java.lang.Long and java.lang.Integer are in module java.base of loader 'bootstrap')]
    java.lang.ClassCastException: class java.lang.Long cannot be cast to class java.lang.Integer (java.lang.Long and java.lang.Integer are in module java.base of loader 'bootstrap')
    	at java.base/java.util.stream.Collectors.lambda$summingInt$19(Collectors.java:673)
    	at reactor.core.publisher.MonoStreamCollector$StreamCollectorSubscriber.onNext(MonoStreamCollector.java:132)
    	at reactor.core.publisher.FluxFlatMap$FlatMapMain.tryEmit(FluxFlatMap.java:543)
    	at reactor.core.publisher.FluxFlatMap$FlatMapInner.onNext(FluxFlatMap.java:984)
    	at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:200)
    	at reactor.core.publisher.FluxConcatArray$ConcatArrayDelayErrorSubscriber.onNext(FluxConcatArray.java:364)
    	at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.onNext(FluxFilterFuseable.java:118)
    	at reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onNext(FluxMapFuseable.java:299)
    	at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2398)
    	at reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.request(FluxMapFuseable.java:360)
    	at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.request(FluxFilterFuseable.java:191)
    	at reactor.core.publisher.FluxConcatArray$ConcatArrayDelayErrorSubscriber.request(FluxConcatArray.java:461)
    	at reactor.core.publisher.FluxPeek$PeekSubscriber.request(FluxPeek.java:138)
    	at reactor.core.publisher.FluxFlatMap$FlatMapInner.onSubscribe(FluxFlatMap.java:964)
    	at reactor.core.publisher.FluxPeek$PeekSubscriber.onSubscribe(FluxPeek.java:171)
    	at reactor.core.publisher.FluxConcatArray$ConcatArrayDelayErrorSubscriber.onSubscribe(FluxConcatArray.java:350)
    	at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.onSubscribe(FluxFilterFuseable.java:87)
    	at reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onSubscribe(FluxMapFuseable.java:265)
    	at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:55)
    	at reactor.core.publisher.Flux.subscribe(Flux.java:8466)
    	at reactor.core.publisher.FluxConcatArray$ConcatArrayDelayErrorSubscriber.onComplete(FluxConcatArray.java:443)
    	at reactor.core.publisher.FluxConcatArray.subscribe(FluxConcatArray.java:73)
    	at reactor.core.publisher.Flux.subscribe(Flux.java:8466)
    	at reactor.core.publisher.FluxFlatMap$FlatMapMain.onNext(FluxFlatMap.java:426)
    	at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onNext(FluxOnAssembly.java:539)
    	at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:122)
    	at reactor.core.publisher.MonoFlatMapMany$FlatMapManyInner.onNext(MonoFlatMapMany.java:250)
    	at reactor.core.publisher.FluxUsingWhen$UsingWhenSubscriber.onNext(FluxUsingWhen.java:345)
    	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79)
    	at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:200)
    	at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:122)
    	at reactor.core.publisher.FluxConcatArray$ConcatArraySubscriber.onNext(FluxConcatArray.java:201)
    	at reactor.core.publisher.MonoFlatMapMany$FlatMapManyInner.onNext(MonoFlatMapMany.java:250)
    	at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2398)
    	at reactor.core.publisher.MonoFlatMapMany$FlatMapManyMain.onSubscribeInner(MonoFlatMapMany.java:150)
    	at reactor.core.publisher.MonoFlatMapMany$FlatMapManyMain.onNext(MonoFlatMapMany.java:189)
    	at reactor.core.publisher.MonoCreate$DefaultMonoSink.success(MonoCreate.java:172)
    	at oracle.r2dbc.impl.AsyncLock.lambda$get$2(AsyncLock.java:167)
    	at oracle.r2dbc.impl.AsyncLock.unlock(AsyncLock.java:125)
    	at oracle.r2dbc.impl.AsyncLock$UsingConnectionSubscriber.terminate(AsyncLock.java:516)
    	at oracle.r2dbc.impl.AsyncLock$UsingConnectionSubscriber.onComplete(AsyncLock.java:502)
    	at reactor.core.publisher.StrictSubscriber.onComplete(StrictSubscriber.java:123)
    	at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onComplete(Operators.java:2058)
    	at org.reactivestreams.FlowAdapters$FlowToReactiveSubscriber.onComplete(FlowAdapters.java:221)
    	at oracle.jdbc.internal.CompletionStageUtil$IteratorSubscription.emitComplete(CompletionStageUtil.java:804)
    	at oracle.jdbc.internal.CompletionStageUtil$IteratorSubscription.emitItems(CompletionStageUtil.java:751)
    	at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1426)
    	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
    	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
    	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
    	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
    	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)
    
    
    opened by rathoreamrsingh 5
  • UDP Implementation

    UDP Implementation

    Fixes #83. As explained and discussed in the issue, neither Oracle's R2DBC driver nor R2DBC itself support user defined datatypes within itself. I'm not aware about other databases, but my project used several UDTs within it, and the lack of support is causing me some issues to migrate my project to a reactive stack. Hence, my PR for the same.

    I've created a custom class UserDefinedType (Implementing Type class) that records the SQL type to map to (the Java class corresponding it) and the type name (string).

    .bind(1, Parameters.Out(new UserDefinedType(java.sql.Array.class, "typeName"))
    

    After this, its relatively straightforward: every time we operate on the Type object, we check if its an instance of UserDefinedType or not and tweak it accordingly.

    opened by nirmalhk7 4
  • WIP: Oracle Database 21.3 XE Test Action

    WIP: Oracle Database 21.3 XE Test Action

    This is a work in progress. I'm creating the pull request in order to verify if the new test action is working correctly.

    This branch adds a new action to the github workflow. It will create and run a docker image of Oracle Database 21.3 XE, and then verify Oracle R2DBC with this database.

    This action will execute along side the existing test action for the 18.4 XE database.

    opened by Michael-A-McMahon 3
  • AQ support via R2DBC

    AQ support via R2DBC

    Maybe it's premature, but I can hope :)

    One awesome Oracle feature that could greatly profit from R2DBC support is Oracle AQ. Instead of blocking on DBMS_AQ.DEQUEUE calls, I could imagine a Publisher per queue that clients could subscribe to in various ways. Are there any plans for this yet, or too soon?

    opened by lukaseder 7
Releases(1.1.0)
Owner
Oracle
Open Source at Oracle
Oracle
JDBC driver for ClickHouse

This is a basic and restricted implementation of jdbc driver for ClickHouse. It has support of a minimal subset of features to be usable.

ClickHouse 1.1k Jan 1, 2023
A JDBC driver for Cloudflare's D1 product, compatible with Jetbrains tools.

D1 JDBC Driver A JDBC driver for Cloudflare's D1 Database product! JDBC is the technology that drives popular database tools such as Jetbrains' databa

Isaac McFadyen 21 Dec 9, 2022
Apache Druid: a high performance real-time analytics database.

Website | Documentation | Developer Mailing List | User Mailing List | Slack | Twitter | Download Apache Druid Druid is a high performance real-time a

The Apache Software Foundation 12.3k Jan 1, 2023
eXist Native XML Database and Application Platform

eXist-db Native XML Database eXist-db is a high-performance open source native XML database—a NoSQL document database and application platform built e

eXist-db.org 363 Dec 30, 2022
Flyway by Redgate • Database Migrations Made Easy.

Flyway by Redgate Database Migrations Made Easy. Evolve your database schema easily and reliably across all your instances. Simple, focused and powerf

Flyway by Boxfuse 6.9k Jan 9, 2023
MapDB provides concurrent Maps, Sets and Queues backed by disk storage or off-heap-memory. It is a fast and easy to use embedded Java database engine.

MapDB: database engine MapDB combines embedded database engine and Java collections. It is free under Apache 2 license. MapDB is flexible and can be u

Jan Kotek 4.6k Dec 30, 2022
Realm is a mobile database: a replacement for SQLite & ORMs

Realm is a mobile database that runs directly inside phones, tablets or wearables. This repository holds the source code for the Java version of Realm

Realm 11.4k Jan 5, 2023
Transactional schema-less embedded database used by JetBrains YouTrack and JetBrains Hub.

JetBrains Xodus is a transactional schema-less embedded database that is written in Java and Kotlin. It was initially developed for JetBrains YouTrack

JetBrains 1k Dec 14, 2022
Flyway by Redgate • Database Migrations Made Easy.

Flyway by Redgate Database Migrations Made Easy. Evolve your database schema easily and reliably across all your instances. Simple, focused and powerf

Flyway by Boxfuse 6.9k Jan 5, 2023
MapDB provides concurrent Maps, Sets and Queues backed by disk storage or off-heap-memory. It is a fast and easy to use embedded Java database engine.

MapDB: database engine MapDB combines embedded database engine and Java collections. It is free under Apache 2 license. MapDB is flexible and can be u

Jan Kotek 4.6k Jan 1, 2023
ObjectBox is a superfast lightweight database for objects

ObjectBox Java (Kotlin, Android) ObjectBox is a superfast object-oriented database with strong relation support. ObjectBox is embedded into your Andro

ObjectBox 4.1k Dec 30, 2022
CrateDB is a distributed SQL database that makes it simple to store and analyze massive amounts of machine data in real-time.

About CrateDB is a distributed SQL database that makes it simple to store and analyze massive amounts of machine data in real-time. CrateDB offers the

Crate.io 3.6k Jan 2, 2023
Transactional schema-less embedded database used by JetBrains YouTrack and JetBrains Hub.

JetBrains Xodus is a transactional schema-less embedded database that is written in Java and Kotlin. It was initially developed for JetBrains YouTrack

JetBrains 858 Mar 12, 2021
Java implementation of Condensation - a zero-trust distributed database that ensures data ownership and data security

Java implementation of Condensation About Condensation enables to build modern applications while ensuring data ownership and security. It's a one sto

CondensationDB 43 Oct 19, 2022
Bu projede Mernis ile Tc kimlik no doğrulanarak database kayıt simülasyonu gerçekleştirildi.

?? CoffeShop Proje Hakkında Nitelikli Yazılımcı Geliştirme kampına aittir. Bu projede Mernis ile Tc kimlik no doğrulanarak database kayıt simülasyonu

Atakan Reyhanioglu 5 Dec 13, 2021
blockchain database, cata metadata query

Drill Storage Plugin for IPFS 中文 Contents Introduction Compile Install Configuration Run Introduction Minerva is a storage plugin of Drill that connec

null 145 Dec 7, 2022
DbLoadgen: A Scalable Solution for Generating Transactional Load Against a Database

DbLoadgen: A Scalable Solution for Generating Transactional Load Against a Database DbLoadgen is scalable solution for generating transactional loads

Qlik Partner Engineering 4 Feb 23, 2022