oracle-r2dbc
oracle-r2dbc copied to clipboard
java.lang.UnsupportedOperationException: This method is deprecated for removal
Hi,
Although the existing previous issues but I feel confused about what to do. So In this issue I will summarize what I am facing.
Development environment: Spring, R2DBC, Oracle DB
Versions: spring boot --> 2.7.0 , Oracle R2DBC --> 0.4.0
Task Objective: reading a specific entity from the db with its related entities using a customized written sql statement to make one single DB query for all data.
The repository code that retrieves the data:
@repository public class MyCustomRepository { private static final String query ="..."; private final DatabaseClient databaseClient; //org.springframework.r2dbc.core.DatabaseClient this.databaseClient.sql(query) // .bind("fName", fName) // .bind("lName", lName) // .fetch().all() // s .bufferUntilChanged(person -> person.get("id")) // .map(.......) }
Observations:
-
previous observation: primarily, I got the error "Failed to obtain R2DBC, this publisher does not support multiple subscribers", even if I specify the version of oracle-r2db, r2dbc-spi and r2dbc-pool explicitly to be
<oracle-r2dbc.version>0.2.0</oracle-r2dbc.version> <r2dbc-spi.version>0.9.0.M1</r2dbc-spi.version> <r2dbc-pool.version>0.9.0.M1</r2dbc-pool.version>
-
current observation: java.lang.UnsupportedOperationException: This method is deprecated for removal getColumnNames(). Based on the previous observation, I tried two different solutions:
- Using bom Borca-SR1
- using Spring 2.7.0 with oracle-r2dbc 0.4.0 (current implemented solution) but both of them raise the mentioned exception of depricated method getColumnNames()
I think this method is called in bufferUntilChanged(), so execluding it exciplicitly is not possible. The method bufferUntilChanged() helps me to aggregate each person entity with its related entities in map(). Questions:
- Is my thought that bufferUntilChanged() call getColumnNames() right? Should it be changed in bufferUntilChanged() implementation?
- Is there any way to decouple getColumnName() from bufferUntilChanged()?
- Is there any alternative to the method bufferUntilChanged() that does not raise such exception?
Sorry for the long description but as I am new to the thema I wanted o make sure to pull all the info. as much as spossible
I think you're right; The bufferUntilChanged operator has a call to person.get("id"). I suspect the get(String) method is implemented to call getColumnNames(), as the "id" string looks like a column name. If you can share a stack trace for the UnsupportedOperationException, then we can confirm where the call to getColumnNames is coming from.
Standard disclaimer: I have almost no experience working with Spring. However, I think the person object is implemented or generated by Spring Data R2DBC? If so, that would mean the version of Spring Data R2DBC you have is calling getColumnNames. I'd wonder then if there is a newer version of Spring Data R2DBC you can use? A newer version should not be calling the deprecated method.
BTW, no need to apologize for long descriptions; Detail is something that I appreciate :)
@Michael-A-McMahon I checked the stack trace and the ,method calls sequence. It seems that the method org.springframework.r2dbc.core.ColumnMapRowMapper.apply(Row row, RowMetadata rowMetadata) uses the depricated method oracle.r2dbc.impl.ReadablesMetadata.RowMetadataImpl.getColumnNames(). The interface that is implemented by this class stated that it is a deprecated method and other alternatives should be used like {@link #contains(String)} or {@link #getColumnMetadatas()} instead. The class is implemented by Mark Paluch (@mp911de).
Original Stack Trace: at oracle.r2dbc.impl.ReadablesMetadata$RowMetadataImpl.getColumnNames(ReadablesMetadata.java:253) ~[oracle-r2dbc-0.4.0.jar:0.4.0] at org.springframework.r2dbc.core.ColumnMapRowMapper.apply(ColumnMapRowMapper.java:57) ~[spring-r2dbc-5.3.20.jar:5.3.20] at org.springframework.r2dbc.core.ColumnMapRowMapper.apply(ColumnMapRowMapper.java:49) ~[spring-r2dbc-5.3.20.jar:5.3.20] at oracle.r2dbc.impl.OracleResultImpl.lambda$map$5(OracleResultImpl.java:222) ~[oracle-r2dbc-0.4.0.jar:0.4.0] at oracle.r2dbc.impl.OracleResultImpl.lambda$publishSegments$1(OracleResultImpl.java:152) ~[oracle-r2dbc-0.4.0.jar:0.4.0] at oracle.r2dbc.impl.OracleResultImpl$ResultSetResult.lambda$publishSegments$0(OracleResultImpl.java:481) ~[oracle-r2dbc-0.4.0.jar:0.4.0] at oracle.r2dbc.impl.OracleReactiveJdbcAdapter.lambda$publishRows$13(OracleReactiveJdbcAdapter.java:751) ~[oracle-r2dbc-0.4.0.jar:0.4.0] at oracle.jdbc.driver.InsensitiveScrollableResultSet$RowPublisher.mapCurrentRow(InsensitiveScrollableResultSet.java:1329) ~[ojdbc11-21.5.0.0.jar:21.5.0.0.0] at oracle.jdbc.driver.InsensitiveScrollableResultSet$RowPublisher.lambda$enqueueMapCurrentRow$3(InsensitiveScrollableResultSet.java:1314) ~[ojdbc11-21.5.0.0.jar:21.5.0.0.0] at oracle.jdbc.driver.RestrictedLock.lockAsync(RestrictedLock.java:506) ~[ojdbc11-21.5.0.0.jar:21.5.0.0.0] at oracle.jdbc.driver.PhysicalConnection.enqueueTask(PhysicalConnection.java:11750) ~[ojdbc11-21.5.0.0.jar:21.5.0.0.0] at oracle.jdbc.driver.InsensitiveScrollableResultSet$RowPublisher.enqueueMapCurrentRow(InsensitiveScrollableResultSet.java:1312) ~[ojdbc11-21.5.0.0.jar:21.5.0.0.0] at oracle.jdbc.driver.InsensitiveScrollableResultSet$RowPublisher.advancePhaseAsync(InsensitiveScrollableResultSet.java:1277) ~[ojdbc11-21.5.0.0.jar:21.5.0.0.0] at oracle.jdbc.driver.PhasedPublisher$PublishingPhaser.onAdvance(PhasedPublisher.java:194) ~[ojdbc11-21.5.0.0.jar:21.5.0.0.0] at java.util.concurrent.Phaser.doArrive(Phaser.java:389) ~[?:?] at java.util.concurrent.Phaser.arrive(Phaser.java:624) ~[?:?] at oracle.jdbc.driver.PhasedPublisher$PhasedSubscription.arriveForNextPhase(PhasedPublisher.java:569) ~[ojdbc11-21.5.0.0.jar:21.5.0.0.0] at oracle.jdbc.driver.PhasedPublisher$PhasedSubscription.request(PhasedPublisher.java:525) ~[ojdbc11-21.5.0.0.jar:21.5.0.0.0] at org.reactivestreams.FlowAdapters$ReactiveToFlowSubscription.request(FlowAdapters.java:189) ~[reactive-streams-1.0.3.jar:?] at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2194) ~[reactor-core-3.4.18.jar:3.4.18] at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onSubscribe(FluxOnErrorResume.java:74) ~[reactor-core-3.4.18.jar:3.4.18] at org.reactivestreams.FlowAdapters$FlowToReactiveSubscriber.onSubscribe(FlowAdapters.java:213) ~[reactive-streams-1.0.3.jar:?] at oracle.jdbc.driver.PhasedPublisher.subscribe(PhasedPublisher.java:344) ~[ojdbc11-21.5.0.0.jar:21.5.0.0.0] at org.reactivestreams.FlowAdapters$ReactivePublisherFromFlow.subscribe(FlowAdapters.java:355) ~[reactive-streams-1.0.3.jar:?] at oracle.r2dbc.impl.OracleReactiveJdbcAdapter.lambda$deferOnce$26(OracleReactiveJdbcAdapter.java:1108) ~[oracle-r2dbc-0.4.0.jar:0.4.0] at reactor.core.publisher.FluxSource.subscribe(FluxSource.java:67) ~[reactor-core-3.4.18.jar:3.4.18] at reactor.core.publisher.Flux.subscribe(Flux.java:8469) ~[reactor-core-3.4.18.jar:3.4.18] at oracle.r2dbc.impl.AsyncLock.lambda$lock$4(AsyncLock.java:203) ~[oracle-r2dbc-0.4.0.jar:0.4.0] at oracle.r2dbc.impl.AsyncLock.lock(AsyncLock.java:99) ~[oracle-r2dbc-0.4.0.jar:0.4.0] at oracle.r2dbc.impl.AsyncLock.lambda$lock$5(AsyncLock.java:202) ~[oracle-r2dbc-0.4.0.jar:0.4.0] at oracle.r2dbc.impl.OracleReactiveJdbcAdapter.lambda$publishRows$15(OracleReactiveJdbcAdapter.java:759) ~[oracle-r2dbc-0.4.0.jar:0.4.0] at reactor.core.publisher.FluxSource.subscribe(FluxSource.java:67) ~[reactor-core-3.4.18.jar:3.4.18] at reactor.core.publisher.Flux.subscribe(Flux.java:8469) ~[reactor-core-3.4.18.jar:3.4.18] at reactor.core.publisher.FluxConcatArray$ConcatArrayDelayErrorSubscriber.onComplete(FluxConcatArray.java:443) ~[reactor-core-3.4.18.jar:3.4.18] at reactor.core.publisher.FluxConcatArray.subscribe(FluxConcatArray.java:73) ~[reactor-core-3.4.18.jar:3.4.18] at reactor.core.publisher.InternalFluxOperator.subscribe(InternalFluxOperator.java:62) ~[reactor-core-3.4.18.jar:3.4.18] at reactor.core.publisher.FluxDefer.subscribe(FluxDefer.java:54) ~[reactor-core-3.4.18.jar:3.4.18] at reactor.core.publisher.Flux.subscribe(Flux.java:8469) ~[reactor-core-3.4.18.jar:3.4.18] at reactor.core.publisher.FluxFlatMap$FlatMapMain.onNext(FluxFlatMap.java:426) ~[reactor-core-3.4.18.jar:3.4.18] at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:129) ~[reactor-core-3.4.18.jar:3.4.18] at reactor.core.publisher.MonoFlatMapMany$FlatMapManyInner.onNext(MonoFlatMapMany.java:250) ~[reactor-core-3.4.18.jar:3.4.18] at reactor.core.publisher.FluxUsingWhen$UsingWhenSubscriber.onNext(FluxUsingWhen.java:345) ~[reactor-core-3.4.18.jar:3.4.18] at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79) ~[reactor-core-3.4.18.jar:3.4.18] at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onNext(FluxPeekFuseable.java:210) ~[reactor-core-3.4.18.jar:3.4.18] at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:129) ~[reactor-core-3.4.18.jar:3.4.18] at reactor.core.publisher.FluxConcatArray$ConcatArraySubscriber.onNext(FluxConcatArray.java:201) ~[reactor-core-3.4.18.jar:3.4.18] at reactor.core.publisher.MonoFlatMapMany$FlatMapManyInner.onNext(MonoFlatMapMany.java:250) ~[reactor-core-3.4.18.jar:3.4.18] at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2398) ~[reactor-core-3.4.18.jar:3.4.18] at reactor.core.publisher.MonoFlatMapMany$FlatMapManyMain.onSubscribeInner(MonoFlatMapMany.java:150) ~[reactor-core-3.4.18.jar:3.4.18] at reactor.core.publisher.MonoFlatMapMany$FlatMapManyMain.onNext(MonoFlatMapMany.java:189) ~[reactor-core-3.4.18.jar:3.4.18] at reactor.core.publisher.MonoCreate$DefaultMonoSink.success(MonoCreate.java:172) ~[reactor-core-3.4.18.jar:3.4.18] at oracle.r2dbc.impl.AsyncLock.lambda$get$2(AsyncLock.java:163) ~[oracle-r2dbc-0.4.0.jar:0.4.0] at oracle.r2dbc.impl.AsyncLock.unlock(AsyncLock.java:122) ~[oracle-r2dbc-0.4.0.jar:0.4.0] at oracle.r2dbc.impl.AsyncLock$UsingConnectionSubscriber.terminate(AsyncLock.java:510) ~[oracle-r2dbc-0.4.0.jar:0.4.0] at oracle.r2dbc.impl.AsyncLock$UsingConnectionSubscriber.onComplete(AsyncLock.java:496) ~[oracle-r2dbc-0.4.0.jar:0.4.0] at reactor.core.publisher.StrictSubscriber.onComplete(StrictSubscriber.java:123) ~[reactor-core-3.4.18.jar:3.4.18] at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onComplete(Operators.java:2058) ~[reactor-core-3.4.18.jar:3.4.18] at org.reactivestreams.FlowAdapters$FlowToReactiveSubscriber.onComplete(FlowAdapters.java:228) ~[reactive-streams-1.0.3.jar:?] at oracle.jdbc.internal.CompletionStageUtil$IteratorSubscription.emitComplete(CompletionStageUtil.java:805) ~[ojdbc11-21.5.0.0.jar:21.5.0.0.0] at oracle.jdbc.internal.CompletionStageUtil$IteratorSubscription.emitItems(CompletionStageUtil.java:752) ~[ojdbc11-21.5.0.0.jar:21.5.0.0.0] at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1426) ~[?:?] at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290) ~[?:?] at java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020) ~[?:?] at java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656) ~[?:?] at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594) ~[?:?]
Spring R2DBC v5.3.20 depends on R2DBC-BOM vArabba-SR13 https://github.com/spring-projects/spring-framework/blob/e0f56e7d80a4e1248198e40be99157dbd8f594af/build.gradle#L33
R2DBC-BOM vArabba-SR13 depends on R2DBC-SPI 0.8.6.RELEASE https://github.com/r2dbc/r2dbc-bom/blob/7f814fe16d7edbb1a25e58a61e2a84400a84573b/pom.xml#L44
So it is "correct" for Spring R2DBC 5.3.20 to call the deprecated method. In the 0.8.6.RELEASE of the SPI, the method is not deprecated.
I see that Spring R2DBC 6.0.0 is getting staged for release. In v6.0.0.M4, the R2DBC-BOM dependency is updated to vBorca-SR1 https://github.com/spring-projects/spring-framework/blob/9215568881ee06e0848e4d2ee3298bc7b2bc8c69/build.gradle#L33
And R2DBC-BOM vBorca-SR1 will update R2DBC-SPI to v0.9.1.RELEASE, and will also update Oracle-R2DBC to v0.4.0 https://github.com/r2dbc/r2dbc-bom/blob/8c2c9d8f6ebf4a3e739455f7af1918ff7825c10f/pom.xml#L42
We can see that in 6.0.0.M4, ColumnMapRowMapper is updated to no longer use the deprecated method. https://github.com/spring-projects/spring-framework/blob/9215568881ee06e0848e4d2ee3298bc7b2bc8c69/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/ColumnMapRowMapper.java#L58
So I think you'll need to update to Spring R2DBC v6.0.0 then. Looks like the .M4 (milestone 4) release is as close as you can get for now. But if you can get stuff working with .M4, I would expect that updating to v6.0.0.RELEASE, once that's available, will be painless.
Closing this issue as it is due to an SPI version incompatibility. I think it will be resolved with the next Spring release.