question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Exception is not thrown when do SQL insert through ReactiveCrudRepository's save method.

See original GitHub issue
  • Driver: r2dbc-mssql 0.8.5.RELEASE, r2dbc-pool 0.8.5.RELEASE, r2dbc-spi 0.8.3.RELEASE, spring-data-r2dbc 1.1.5.RELEASE
  • Database: MS SQL Server 2017
  • Java: Java 11.0.8
  • OS: Windows 10, macOS

##############

Exception is not thrown when do SQL insert through ReactiveCrudRepository’s save method on MS SQL, others database is fine, exception is thrown as expected.

Insert failed with GENERAL_ERROR but no exception thrown.

2020-11-06 10:15:07,449 [reactor-http-nio-2] DEBUG HttpServerOperations - [id: 0x02619bd6, L:/0:0:0:0:0:0:0:1:8104 - R:/0:0:0:0:0:0:0:1:55914] Increasing pending responses, now 1 2020-11-06 10:15:07,449 [reactor-http-nio-2] DEBUG HttpServer - [id: 0x02619bd6, L:/0:0:0:0:0:0:0:1:8104 - R:/0:0:0:0:0:0:0:1:55914] Handler is being applied: org.springframework.http.server.reactive.ReactorHttpHandlerAdapter@59fb2723 2020-11-06 10:15:07,449 [reactor-http-nio-2] DEBUG HttpWebHandlerAdapter - [02619bd6-2] HTTP POST “/api/1.0/test_record” 2020-11-06 10:15:07,450 [boundedElastic-1] DEBUG DefaultWebSessionManager - Created new WebSession. … … 2020-11-06 10:15:07,507 [reactor-http-nio-2] DEBUG Jackson2JsonDecoder - [02619bd6-2] Decoded [Customer(customerId=null, name=XVeryGeorge)] 2020-11-06 10:15:07,507 [reactor-http-nio-2] INFO TestHandler - Request data -> Customer(customerId=null, name=XVeryGeorge) 2020-11-06 10:15:07,507 [reactor-http-nio-2] DEBUG ConnectionPool - Obtaining new connection from the driver 2020-11-06 10:15:07,507 [reactor-http-nio-2] DEBUG DefaultDatabaseClient - Executing SQL statement [INSERT INTO customer (name) VALUES (@P0_name)] 2020-11-06 10:15:07,507 [reactor-http-nio-2] DEBUG MssqlConnection - [cid: 0x5] Creating statement for SQL: [INSERT INTO customer (name) VALUES (@P0_name)] 2020-11-06 10:15:07,508 [reactor-http-nio-2] DEBUG ParametrizedMssqlStatement - [cid: 0x5] Start direct exchange for INSERT INTO customer (name) VALUES (@P0_name) SELECT SCOPE_IDENTITY() AS GENERATED_KEYS 2020-11-06 10:15:07,508 [reactor-http-nio-2] DEBUG ReactorNettyClient - [cid: 0x5] exchange() 2020-11-06 10:15:07,508 [reactor-http-nio-2] DEBUG MssqlResult - [cid: 0x5] Creating new result 2020-11-06 10:15:07,508 [reactor-http-nio-2] DEBUG QUERY - [cid: 0x5] Executing query: INSERT INTO customer (name) VALUES (@P0_name) SELECT SCOPE_IDENTITY() AS GENERATED_KEYS 2020-11-06 10:15:07,508 [reactor-http-nio-2] DEBUG ReactorNettyClient - [cid: 0x5] exchange(subscribed) 2020-11-06 10:15:07,508 [reactor-http-nio-2] DEBUG ReactorNettyClient - [cid: 0x5] Initiating exchange 2020-11-06 10:15:07,508 [reactor-http-nio-2] DEBUG ReactorNettyClient - [cid: 0x5] Request: RPCRequest [procName=‘null’, procId=10, optionFlags=io.r2dbc.mssql.message.token.RpcRequest$OptionFlags@12de1291, statusFlags=0, parameterDescriptors=[RpcString [name=‘null’, value=INSERT INTO customer (name) VALUES (@P0_name) SELECT SCOPE_IDENTITY() AS GENERATED_KEYS], RpcString [name=‘null’, value=@P0_name nvarchar(4000)], EncodedRpcParameter [name=‘P0_name’, value=io.r2dbc.mssql.codec.CharacterEncoder$NvarcharEncoded@7a295649]]] 2020-11-06 10:15:07,523 [reactor-tcp-nio-1] DEBUG ReactorNettyClient - [cid: 0x5] Response: ErrorToken [number=8152, state=2, infoClass=16, message=‘String or binary data would be truncated.“, serverName='SRV_TEST”, procName=’“, lineNumber=16777216] 2020-11-06 10:15:07,523 [reactor-tcp-nio-1] DEBUG ReactorNettyClient - [cid: 0x5] Warning: Code [8152] Severity [GENERAL_ERROR]: String or binary data would be truncated. 2020-11-06 10:15:07,523 [reactor-tcp-nio-1] DEBUG ReactorNettyClient - [cid: 0x5] Response: InfoToken [number=3621, state=0, infoClass=0, message='The statement has been terminated.”, serverName=‘SRV_TEST", procName=’“, lineNumber=16777216] 2020-11-06 10:15:07,523 [reactor-tcp-nio-1] DEBUG ReactorNettyClient - [cid: 0x5] Info: Code [3621] Severity [INFORMATIONAL]: The statement has been terminated. 2020-11-06 10:15:07,523 [reactor-tcp-nio-1] DEBUG ReactorNettyClient - [cid: 0x5] Response: DoneInProcToken [done=false, hasCount=false, rowCount=0, hasMore=true, currentCommand=195] 2020-11-06 10:15:07,523 [reactor-tcp-nio-1] DEBUG ReactorNettyClient - [cid: 0x5] Response: ColumnMetadataToken [columns=[Column [name='GENERATED_KEYS”, type=MutableTypeInformation [maxLength=17, lengthStrategy=BYTELENTYPE, precision=38, displaySize=40, scale=0, flags=33, serverType=numeric, userType=0, udtTypeName=“null”, collation=null, charset=null], table=null]]] 2020-11-06 10:15:07,523 [reactor-tcp-nio-1] DEBUG MssqlResult - [cid: 0x5] Result column definition: ColumnMetadataToken [columns=[Column [name='GENERATED_KEYS", type=MutableTypeInformation [maxLength=17, lengthStrategy=BYTELENTYPE, precision=38, displaySize=40, scale=0, flags=33, serverType=numeric, userType=0, udtTypeName=“null”, collation=null, charset=null], table=null]]] 2020-11-06 10:15:07,523 [reactor-tcp-nio-1] DEBUG ReactorNettyClient - [cid: 0x5] Response: io.r2dbc.mssql.message.token.RowToken@5d054679 2020-11-06 10:15:07,523 [reactor-tcp-nio-1] DEBUG PooledConnection - Releasing connection 2020-11-06 10:15:07,524 [reactor-tcp-nio-1] INFO TestHandler - >>>>>>>>> Recorded -> Customer(customerId=null, name=XVeryGeorge) 2020-11-06 10:15:07,524 [reactor-tcp-nio-1] DEBUG Jackson2JsonEncoder - [02619bd6-2] Encoding [CommonRespMessage(code=null, status=OK, message=null, reference=null)] 2020-11-06 10:15:07,524 [reactor-tcp-nio-1] DEBUG FluxDiscardOnCancel - received cancel signal 2020-11-06 10:15:07,524 [reactor-tcp-nio-1] DEBUG ReactorNettyClient - [cid: 0x5] Response: DoneInProcToken [done=false, hasCount=true, rowCount=1, hasMore=true, currentCommand=0] 2020-11-06 10:15:07,524 [reactor-tcp-nio-1] DEBUG ReactorNettyClient - [cid: 0x5] Response: ReturnStatus [status=0] 2020-11-06 10:15:07,525 [reactor-tcp-nio-1] DEBUG ReactorNettyClient - [cid: 0x5] Response: DoneProcToken [done=true, hasCount=false, rowCount=0, hasMore=false, currentCommand=0] 2020-11-06 10:15:07,525 [reactor-tcp-nio-1] DEBUG ReactorNettyClient - [cid: 0x5] Conversation complete 2020-11-06 10:15:07,525 [reactor-http-nio-2] DEBUG HttpServerOperations - [id: 0x02619bd6, L:/0:0:0:0:0:0:0:1:8104 - R:/0:0:0:0:0:0:0:1:55914] Decreasing pending responses, now 0 2020-11-06 10:15:07,525 [reactor-http-nio-2] DEBUG HttpWebHandlerAdapter - [02619bd6-2] Completed 200 OK 2020-11-06 10:15:07,525 [reactor-http-nio-2] DEBUG HttpServerOperations - [id: 0x02619bd6, L:/0:0:0:0:0:0:0:1:8104 - R:/0:0:0:0:0:0:0:1:55914] Last HTTP response frame 2020-11-06 10:15:07,525 [reactor-http-nio-2] DEBUG HttpServerOperations - [id: 0x02619bd6, L:/0:0:0:0:0:0:0:1:8104 - R:/0:0:0:0:0:0:0:1:55914] Last HTTP packet was sent, terminating the channel

Update failed with same GENERAL_ERROR, the exception thrown and can be handled as expected.

2020-11-06 10:21:26,159 [reactor-http-nio-2] DEBUG HttpServerOperations - [id: 0x086448f9, L:/0:0:0:0:0:0:0:1:8104 - R:/0:0:0:0:0:0:0:1:56012] Increasing pending responses, now 1 2020-11-06 10:21:26,159 [reactor-http-nio-2] DEBUG HttpServer - [id: 0x086448f9, L:/0:0:0:0:0:0:0:1:8104 - R:/0:0:0:0:0:0:0:1:56012] Handler is being applied: org.springframework.http.server.reactive.ReactorHttpHandlerAdapter@76960762 2020-11-06 10:21:26,159 [reactor-http-nio-2] DEBUG HttpWebHandlerAdapter - [086448f9-2] HTTP POST “/api/1.0/test_record” 2020-11-06 10:21:26,160 [boundedElastic-2] DEBUG DefaultWebSessionManager - Created new WebSession. … … 2020-11-06 10:21:26,224 [reactor-http-nio-2] DEBUG Jackson2JsonDecoder - [086448f9-2] Decoded [Customer(customerId=c016d098-0449-4851-b4a4-72472c410448, name=XVeryGeorge)] 2020-11-06 10:21:26,224 [reactor-http-nio-2] INFO TestHandler - Request data -> Customer(customerId=c016d098-0449-4851-b4a4-72472c410448, name=XVeryGeorge) 2020-11-06 10:21:26,224 [reactor-http-nio-2] DEBUG ConnectionPool - Obtaining new connection from the driver 2020-11-06 10:21:26,224 [reactor-http-nio-2] DEBUG DefaultDatabaseClient - Executing SQL statement [UPDATE customer SET name = @P0_name WHERE customer.customer_id = @P1_customerid] 2020-11-06 10:21:26,224 [reactor-http-nio-2] DEBUG MssqlConnection - [cid: 0x5] Creating statement for SQL: [UPDATE customer SET name = @P0_name WHERE customer.customer_id = @P1_customerid] 2020-11-06 10:21:26,225 [reactor-http-nio-2] DEBUG ParametrizedMssqlStatement - [cid: 0x5] Start direct exchange for UPDATE customer SET name = @P0_name WHERE customer.customer_id = @P1_customerid 2020-11-06 10:21:26,225 [reactor-http-nio-2] DEBUG ReactorNettyClient - [cid: 0x5] exchange() 2020-11-06 10:21:26,225 [reactor-http-nio-2] DEBUG MssqlResult - [cid: 0x5] Creating new result 2020-11-06 10:21:26,225 [reactor-http-nio-2] DEBUG QUERY - [cid: 0x5] Executing query: UPDATE customer SET name = @P0_name WHERE customer.customer_id = @P1_customerid 2020-11-06 10:21:26,225 [reactor-http-nio-2] DEBUG ReactorNettyClient - [cid: 0x5] exchange(subscribed) 2020-11-06 10:21:26,225 [reactor-http-nio-2] DEBUG ReactorNettyClient - [cid: 0x5] Initiating exchange 2020-11-06 10:21:26,225 [reactor-http-nio-2] DEBUG ReactorNettyClient - [cid: 0x5] Request: RPCRequest [procName=‘null’, procId=10, optionFlags=io.r2dbc.mssql.message.token.RpcRequest$OptionFlags@6ce647a6, statusFlags=0, parameterDescriptors=[RpcString [name=‘null’, value=UPDATE customer SET name = @P0_name WHERE customer.customer_id = @P1_customerid], RpcString [name=‘null’, value=@P0_name nvarchar(4000),@P1_customerid uniqueidentifier], EncodedRpcParameter [name=‘P0_name’, value=io.r2dbc.mssql.codec.CharacterEncoder$NvarcharEncoded@3432848f], EncodedRpcParameter [name=‘P1_customerid’, value=io.r2dbc.mssql.codec.RpcEncoding$HintedEncoded@3515a4a]]] 2020-11-06 10:21:26,249 [reactor-tcp-nio-1] DEBUG ReactorNettyClient - [cid: 0x5] Response: ErrorToken [number=8152, state=2, infoClass=16, message=‘String or binary data would be truncated.“, serverName='SRV_TEST”, procName=’“, lineNumber=16777216] 2020-11-06 10:21:26,249 [reactor-tcp-nio-1] DEBUG ReactorNettyClient - [cid: 0x5] Warning: Code [8152] Severity [GENERAL_ERROR]: String or binary data would be truncated. 2020-11-06 10:21:26,249 [reactor-tcp-nio-1] DEBUG ReactorNettyClient - [cid: 0x5] Response: InfoToken [number=3621, state=0, infoClass=0, message='The statement has been terminated.”, serverName=‘SRV_TEST", procName=’", lineNumber=16777216] 2020-11-06 10:21:26,249 [reactor-tcp-nio-1] DEBUG ReactorNettyClient - [cid: 0x5] Info: Code [3621] Severity [INFORMATIONAL]: The statement has been terminated. 2020-11-06 10:21:26,249 [reactor-tcp-nio-1] DEBUG ReactorNettyClient - [cid: 0x5] Response: DoneInProcToken [done=false, hasCount=false, rowCount=0, hasMore=true, currentCommand=197] 2020-11-06 10:21:26,250 [reactor-tcp-nio-1] DEBUG ReactorNettyClient - [cid: 0x5] Response: ReturnStatus [status=8152] 2020-11-06 10:21:26,250 [reactor-tcp-nio-1] DEBUG ReactorNettyClient - [cid: 0x5] Response: DoneProcToken [done=true, hasCount=false, rowCount=0, hasMore=false, currentCommand=0] 2020-11-06 10:21:26,250 [reactor-tcp-nio-1] DEBUG FluxDiscardOnCancel - received cancel signal 2020-11-06 10:21:26,250 [reactor-tcp-nio-1] DEBUG PooledConnection - Releasing connection 2020-11-06 10:21:26,250 [reactor-tcp-nio-1] DEBUG SqlStateR2dbcExceptionTranslator - Extracted SQL state class ‘22’ from value ‘22001’ 2020-11-06 10:21:26,251 [reactor-tcp-nio-1] ERROR TestHandler - >>>>>>>>> Error -> execute; SQL [UPDATE customer SET name = @P0_name WHERE customer.customer_id = @P1_customerid]; String or binary data would be truncated.; nested exception is io.r2dbc.mssql.ExceptionFactory$MssqlNonTransientException: [8152] [22001] String or binary data would be truncated. org.springframework.dao.DataIntegrityViolationException: execute; SQL [UPDATE customer SET name = @P0_name WHERE customer.customer_id = @P1_customerid]; String or binary data would be truncated.; nested exception is io.r2dbc.mssql.ExceptionFactory$MssqlNonTransientException: [8152] [22001] String or binary data would be truncated. at org.springframework.data.r2dbc.support.SqlStateR2dbcExceptionTranslator.doTranslate(SqlStateR2dbcExceptionTranslator.java:98) at org.springframework.data.r2dbc.support.AbstractFallbackR2dbcExceptionTranslator.translate(AbstractFallbackR2dbcExceptionTranslator.java:67) at org.springframework.data.r2dbc.support.AbstractFallbackR2dbcExceptionTranslator.translate(AbstractFallbackR2dbcExceptionTranslator.java:76) at org.springframework.data.r2dbc.core.DefaultDatabaseClient.translateException(DefaultDatabaseClient.java:264) at org.springframework.data.r2dbc.core.DefaultDatabaseClient.lambda$inConnection$4(DefaultDatabaseClient.java:172) at reactor.core.publisher.Mono.lambda$onErrorMap$29(Mono.java:3272) at reactor.core.publisher.Mono.lambda$onErrorResume$31(Mono.java:3362) at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:88) at reactor.core.publisher.MonoUsingWhen$MonoUsingWhenSubscriber.deferredError(MonoUsingWhen.java:285) at reactor.core.publisher.FluxUsingWhen$RollbackInner.onComplete(FluxUsingWhen.java:485) at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onComplete(Operators.java:2016) at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:252) at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onComplete(Operators.java:2016) at reactor.core.publisher.Operators$MonoSubscriber.onComplete(Operators.java:1824) at reactor.core.publisher.MonoIgnoreThen$ThenAcceptInner.onComplete(MonoIgnoreThen.java:314) at reactor.core.publisher.Operators$MonoSubscriber.onComplete(Operators.java:1824) at reactor.core.publisher.MonoIgnoreThen$ThenAcceptInner.onComplete(MonoIgnoreThen.java:314) at reactor.pool.SimpleDequePool$QueuePoolRecyclerInner.onComplete(SimpleDequePool.java:624) at reactor.core.publisher.Operators.complete(Operators.java:135) at reactor.core.publisher.MonoEmpty.subscribe(MonoEmpty.java:45) at reactor.core.publisher.Mono.subscribe(Mono.java:4213) at reactor.pool.SimpleDequePool$QueuePoolRecyclerMono.subscribe(SimpleDequePool.java:736) at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.drain(MonoIgnoreThen.java:153) at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:56) at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.drain(MonoIgnoreThen.java:153) at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:56) at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) at reactor.core.publisher.Mono.subscribe(Mono.java:4213) at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:97) at reactor.core.publisher.MonoIgnoreElements$IgnoreElementsSubscriber.onError(MonoIgnoreElements.java:76) at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onError(FluxMapFuseable.java:134) at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.onError(FluxFilterFuseable.java:156) at reactor.core.publisher.FluxFilterFuseable$FilterFuseableConditionalSubscriber.onError(FluxFilterFuseable.java:375) at reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onError(FluxMapFuseable.java:326) at reactor.core.publisher.FluxHandleFuseable$HandleFuseableSubscriber.onNext(FluxHandleFuseable.java:185) at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2344) at reactor.core.publisher.FluxHandleFuseable$HandleFuseableSubscriber.request(FluxHandleFuseable.java:243) at reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.request(FluxMapFuseable.java:346) at reactor.core.publisher.FluxFilterFuseable$FilterFuseableConditionalSubscriber.request(FluxFilterFuseable.java:403) at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.request(FluxFilterFuseable.java:184) at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:162) at reactor.core.publisher.MonoIgnoreElements$IgnoreElementsSubscriber.onSubscribe(MonoIgnoreElements.java:64) at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:90) at reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.onSubscribe(FluxFilterFuseable.java:81) at reactor.core.publisher.FluxFilterFuseable$FilterFuseableConditionalSubscriber.onSubscribe(FluxFilterFuseable.java:298) at reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onSubscribe(FluxMapFuseable.java:255) at reactor.core.publisher.FluxHandleFuseable$HandleFuseableSubscriber.onSubscribe(FluxHandleFuseable.java:148) at reactor.core.publisher.MonoCurrentContext.subscribe(MonoCurrentContext.java:35) at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) at reactor.core.publisher.Mono.subscribe(Mono.java:4213) at reactor.core.publisher.FluxUsingWhen$UsingWhenSubscriber.onError(FluxUsingWhen.java:374) at reactor.core.publisher.MonoStreamCollector$StreamCollectorSubscriber.onError(MonoStreamCollector.java:143) at reactor.core.publisher.FluxFlatMap$FlatMapMain.checkTerminated(FluxFlatMap.java:834) at reactor.core.publisher.FluxFlatMap$FlatMapMain.drainLoop(FluxFlatMap.java:600) at reactor.core.publisher.FluxFlatMap$FlatMapMain.drain(FluxFlatMap.java:580) at reactor.core.publisher.FluxFlatMap$FlatMapMain.innerError(FluxFlatMap.java:855) at reactor.core.publisher.FluxFlatMap$FlatMapInner.onError(FluxFlatMap.java:1006) at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onError(FluxMapFuseable.java:134) at reactor.core.publisher.MonoReduce$ReduceSubscriber.onError(MonoReduce.java:121) at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onError(FluxPeekFuseable.java:227) at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onComplete(FluxPeekFuseable.java:264) at reactor.core.publisher.FluxHandleFuseable$HandleFuseableSubscriber.onComplete(FluxHandleFuseable.java:223) at reactor.core.publisher.FluxContextStart$ContextStartSubscriber.onComplete(FluxContextStart.java:115) at io.r2dbc.mssql.util.FluxDiscardOnCancel$FluxDiscardOnCancelSubscriber.onComplete(FluxDiscardOnCancel.java:104) at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:252) at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:252) at reactor.core.publisher.FluxFilter$FilterSubscriber.onComplete(FluxFilter.java:160) at reactor.core.publisher.FluxHandle$HandleConditionalSubscriber.onComplete(FluxHandle.java:416) at reactor.core.publisher.EmitterProcessor.checkTerminated(EmitterProcessor.java:495) at reactor.core.publisher.EmitterProcessor.drain(EmitterProcessor.java:417) at reactor.core.publisher.EmitterProcessor.onNext(EmitterProcessor.java:274) at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:192) at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:192) at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:192) at reactor.core.publisher.FluxHandle$HandleSubscriber.onNext(FluxHandle.java:112) at reactor.core.publisher.MonoFlatMapMany$FlatMapManyInner.onNext(MonoFlatMapMany.java:242) at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:192) at reactor.core.publisher.EmitterProcessor.drain(EmitterProcessor.java:432) at reactor.core.publisher.EmitterProcessor.onNext(EmitterProcessor.java:274) at io.r2dbc.mssql.client.ReactorNettyClient$1.next(ReactorNettyClient.java:244) at io.r2dbc.mssql.client.ReactorNettyClient$1.next(ReactorNettyClient.java:204) at io.r2dbc.mssql.message.token.Tabular$TabularDecoder.decode(Tabular.java:424) at io.r2dbc.mssql.client.ConnectionState$4$1.decode(ConnectionState.java:206) at io.r2dbc.mssql.client.StreamDecoder.withState(StreamDecoder.java:137) at io.r2dbc.mssql.client.StreamDecoder.decode(StreamDecoder.java:109) at io.r2dbc.mssql.client.ReactorNettyClient.lambda$new$6(ReactorNettyClient.java:254) at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:177) at reactor.netty.channel.FluxReceive.drainReceiver(FluxReceive.java:256) at reactor.netty.channel.FluxReceive.onInboundNext(FluxReceive.java:362) at reactor.netty.channel.ChannelOperations.onInboundNext(ChannelOperations.java:358) at reactor.netty.channel.ChannelOperationsHandler.channelRead(ChannelOperationsHandler.java:96) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:93) at io.r2dbc.mssql.client.ssl.TdsSslHandler.channelRead(TdsSslHandler.java:380) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714) at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650) at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576) at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493) at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989) at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) at java.base/java.lang.Thread.run(Thread.java:834) Caused by: io.r2dbc.mssql.ExceptionFactory$MssqlNonTransientException: String or binary data would be truncated. at io.r2dbc.mssql.ExceptionFactory.createException(ExceptionFactory.java:152) at io.r2dbc.mssql.MssqlResult.lambda$getRowsUpdated$0(MssqlResult.java:112) at reactor.core.publisher.FluxHandleFuseable$HandleFuseableSubscriber.onNext(FluxHandleFuseable.java:163) at reactor.core.publisher.FluxContextStart$ContextStartSubscriber.onNext(FluxContextStart.java:96) at io.r2dbc.mssql.util.FluxDiscardOnCancel$FluxDiscardOnCancelSubscriber.onNext(FluxDiscardOnCancel.java:89) at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:192) at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:192) at reactor.core.publisher.FluxFilter$FilterSubscriber.onNext(FluxFilter.java:107) at reactor.core.publisher.FluxHandle$HandleConditionalSubscriber.onNext(FluxHandle.java:319) at reactor.core.publisher.EmitterProcessor.drain(EmitterProcessor.java:432) … 42 common frames omitted 2020-11-06 10:21:26,251 [reactor-tcp-nio-1] DEBUG Jackson2JsonEncoder - [086448f9-2] Encoding [CommonRespMessage(code=null, status=ERROR, message=null, reference=null)] 2020-11-06 10:21:26,251 [reactor-tcp-nio-1] DEBUG ReactorNettyClient - [cid: 0x5] Conversation complete 2020-11-06 10:21:26,252 [reactor-http-nio-2] DEBUG HttpServerOperations - [id: 0x086448f9, L:/0:0:0:0:0:0:0:1:8104 - R:/0:0:0:0:0:0:0:1:56012] Decreasing pending responses, now 0 2020-11-06 10:21:26,252 [reactor-http-nio-2] DEBUG HttpWebHandlerAdapter - [086448f9-2] Completed 200 OK 2020-11-06 10:21:26,252 [reactor-http-nio-2] DEBUG HttpServerOperations - [id: 0x086448f9, L:/0:0:0:0:0:0:0:1:8104 - R:/0:0:0:0:0:0:0:1:56012] Last HTTP response frame 2020-11-06 10:21:26,252 [reactor-http-nio-2] DEBUG HttpServerOperations - [id: 0x086448f9, L:/0:0:0:0:0:0:0:1:8104 - R:/0:0:0:0:0:0:0:1:56012] Last HTTP packet was sent, terminating the channel

Table schema

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[customer](
	[customer_id] [char](36) NOT NULL,
	[name] [varchar](10) NOT NULL,
PRIMARY KEY CLUSTERED 
(
	[customer_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

Steps to reproduce

The domain “Customer”…

@Table("customer")
data class Customer(
    @Id @Column("customer_id") val customerId: UUID? = null,
    @Column("name") val name: String
) : Persistable<UUID> {
    override fun getId(): UUID? {
        return UUID.randomUUID()
    }

    override fun isNew(): Boolean {
        return customerId == null
    }
}

The controller…

@Transactional
fun record(request: ServerRequest): Mono<ServerResponse> {
    val returnData = request.bodyToMono(Customer::class.java).flatMap { recordRequest ->
        log.info("Request data -> $recordRequest")

        customerRepository.save(recordRequest)
            .flatMap { customer ->
                log.info(">>>>>>>>> Recorded -> $customer")

                CommonRespMessage(status = "OK").toMono()
            }
            .onErrorResume { throwable ->
                log.error(">>>>>>>>> Error -> ${throwable.message}", throwable)

                CommonRespMessage(status = "ERROR").toMono()
            }
    }

    return ServerResponse.ok()
        .contentType(MediaType.APPLICATION_JSON)
        .body(returnData, CommonRespMessage::class.java)
}

Expected behavior/code

Exception must be thrown when r2dbc-mssql receive SQL Error from MS SQL Server.

Possible Solution

Make SQL error handling of INSERT flow the same as UPDATE flow.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:2
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

3reactions
mp911decommented, Mar 9, 2021

Duplicates https://github.com/spring-projects/spring-data-r2dbc/issues/552. The driver emits the row and then sends an error signal which models somewhat the flow within the results. That behavior makes it difficult for consumers to rely on the first result (consume first and then ignore the rest of the response) as the query actually has failed.

I think it’s fair to suppress row emission in case of preceding errors.

2reactions
niciositycommented, Jan 6, 2021

Hi,

I got the same behaviour recently when I tried to upgrade r2dbc-mssql 0.8.3 to 0.8.4.

I think that this regression is appeared with the fix #162. Do you confirm it ?

I didn’t look in to the fix #162 yet but I tried downgrading to r2dbc-mssql 0.8.3 to test the same behavior and expected exception thrown via onErrorDropped. So the fix #162 or maybe other fixes on 0.8.4, 0.8.5 broke this?

From my testing, I think I can confirm that the issue exists on 0.8.4+.

2021-01-06 11:54:14,912 [reactor-tcp-nio-2] ERROR Operators - Operator called default onErrorDropped io.r2dbc.mssql.ExceptionFactory$MssqlNonTransientException: String or binary data would be truncated. at io.r2dbc.mssql.ExceptionFactory.createException(ExceptionFactory.java:152) at io.r2dbc.mssql.ExceptionFactory.createException(ExceptionFactory.java:181) at io.r2dbc.mssql.RpcQueryMessageFlow.lambda$exchange$1(RpcQueryMessageFlow.java:148) at reactor.core.publisher.FluxHandle$HandleConditionalSubscriber.onNext(FluxHandle.java:310) at reactor.core.publisher.EmitterProcessor.drain(EmitterProcessor.java:491) at reactor.core.publisher.EmitterProcessor.tryEmitNext(EmitterProcessor.java:299) at reactor.core.publisher.InternalManySink.emitNext(InternalManySink.java:27) at reactor.core.publisher.EmitterProcessor.onNext(EmitterProcessor.java:265) at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:199) at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:199) at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:199) at reactor.core.publisher.FluxHandle$HandleSubscriber.onNext(FluxHandle.java:118) at reactor.core.publisher.MonoFlatMapMany$FlatMapManyInner.onNext(MonoFlatMapMany.java:250) at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:199) at reactor.core.publisher.EmitterProcessor.drain(EmitterProcessor.java:491) at reactor.core.publisher.EmitterProcessor.tryEmitNext(EmitterProcessor.java:299) at reactor.core.publisher.InternalManySink.emitNext(InternalManySink.java:27) at reactor.core.publisher.EmitterProcessor.onNext(EmitterProcessor.java:265) at io.r2dbc.mssql.client.ReactorNettyClient$1.next(ReactorNettyClient.java:241) at io.r2dbc.mssql.client.ReactorNettyClient$1.next(ReactorNettyClient.java:201) at io.r2dbc.mssql.message.token.Tabular$TabularDecoder.decode(Tabular.java:425) at io.r2dbc.mssql.client.ConnectionState$4$1.decode(ConnectionState.java:206) at io.r2dbc.mssql.client.StreamDecoder.withState(StreamDecoder.java:137) at io.r2dbc.mssql.client.StreamDecoder.decode(StreamDecoder.java:109) at io.r2dbc.mssql.client.ReactorNettyClient.lambda$new$6(ReactorNettyClient.java:251) at reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:184) at reactor.netty.channel.FluxReceive.drainReceiver(FluxReceive.java:265) at reactor.netty.channel.FluxReceive.onInboundNext(FluxReceive.java:371) at reactor.netty.channel.ChannelOperations.onInboundNext(ChannelOperations.java:381) at reactor.netty.channel.ChannelOperationsHandler.channelRead(ChannelOperationsHandler.java:94) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:93) at io.r2dbc.mssql.client.ssl.TdsSslHandler.channelRead(TdsSslHandler.java:380) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719) at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655) at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581) at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493) at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989) at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) at java.base/java.lang.Thread.run(Thread.java:834) 2021-01-06 11:54:14,912 [reactor-tcp-nio-2] DEBUG ReactorNettyClient - [cid: 0x1] Conversation complete

Read more comments on GitHub >

github_iconTop Results From Across the Web

reactive repository throws exception when saving a new object
operation results either in an INSERT or UPDATE statement. Issuing the wrong statement either causes a primary key violation or a no-op as ......
Read more >
Spring Data R2DBC ReactiveCrudRepository.save() method ...
Everything is seems like saved and I can receive response successfully, but in fact, db has no new record and next get query...
Read more >
Spring Data R2DBC - Reference Documentation
These methods are routed into the base repository implementation of the store of your choice provided by Spring Data (for example, if you...
Read more >
[Solved]-reactive repository throws exception when saving a ...
Performing a save(…) operation results either in an INSERT or UPDATE statement. Issuing the wrong statement either causes a primary key violation or...
Read more >
Spring Data R2dbc · Spring WebFlux By Example - Hantsy Bai
Let's add a r2dbc driver for the specific database you are using. ... working in other Spring Data projects, it also supports custom...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found