Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TIMESTAMP can't be decoded into Instant #238

Open
rotilho opened this issue Dec 12, 2022 · 2 comments
Open

TIMESTAMP can't be decoded into Instant #238

rotilho opened this issue Dec 12, 2022 · 2 comments

Comments

@rotilho
Copy link

rotilho commented Dec 12, 2022

Bug Report

Versions

  • Driver: 1.0.0.RELEASE
  • Database: 2.1.214
  • Java: 17
  • OS: Windows 11

Current Behavior

TIMESTAMP can't be decoded into Instant however JDBC implementation seems happy with that. Weirdly, I can save Instant but not query it.

Stack trace
org.springframework.core.convert.ConversionFailedException: Failed to convert from type [io.r2dbc.h2.H2Row] to type [org.atto.node.account.Account] for value 'H2Row{columns=[Column{typeInfo=BINARY VARYING(32), name='PUBLIC_KEY', value=X'9d7817e1e5ba24a83a3d052befcede84ca391fa3911b69a5a99410b5867866d4'}, Column{typeInfo=SMALLINT, name='VERSION', value=CAST(0 AS SMALLINT)}, Column{typeInfo=BIGINT, name='HEIGHT', value=CAST(1 AS BIGINT)}, Column{typeInfo=BIGINT, name='BALANCE', value=-446744073709551616}, Column{typeInfo=BINARY VARYING(32), name='LAST_TRANSACTION_HASH', value=X'0000009d7817e1e5ba24a83a3d052befcede84ca391fa3911b69a5a99410b586'}, Column{typeInfo=TIMESTAMP, name='LAST_TRANSACTION_TIMESTAMP', value=TIMESTAMP '2022-12-12 08:00:25.230894'}, Column{typeInfo=BINARY VARYING(32), name='REPRESENTATIVE', value=X'9d7817e1e5ba24a83a3d052befcede84ca391fa3911b69a5a99410b5867866d4'}, Column{typeInfo=TIMESTAMP, name='PERSISTED_AT', value=TIMESTAMP '2022-12-12 08:00:29.386916'}, Column{typeInfo=TIMESTAMP, name='UPDATED_AT', value=TIMESTAMP '2022-12-12 08:00:29.386916'}], nameKeyedColumns={PERSISTED_AT=Column{typeInfo=TIMESTAMP, name='PERSISTED_AT', value=TIMESTAMP '2022-12-12 08:00:29.386916'}, LAST_TRANSACTION_TIMESTAMP=Column{typeInfo=TIMESTAMP, name='LAST_TRANSACTION_TIMESTAMP', value=TIMESTAMP '2022-12-12 08:00:25.230894'}, PUBLIC_KEY=Column{typeInfo=BINARY VARYING(32), name='PUBLIC_KEY', value=X'9d7817e1e5ba24a83a3d052befcede84ca391fa3911b69a5a99410b5867866d4'}, VERSION=Column{typeInfo=SMALLINT, name='VERSION', value=CAST(0 AS SMALLINT)}, REPRESENTATIVE=Column{typeInfo=BINARY VARYING(32), name='REPRESENTATIVE', value=X'9d7817e1e5ba24a83a3d052befcede84ca391fa3911b69a5a99410b5867866d4'}, UPDATED_AT=Column{typeInfo=TIMESTAMP, name='UPDATED_AT', value=TIMESTAMP '2022-12-12 08:00:29.386916'}, HEIGHT=Column{typeInfo=BIGINT, name='HEIGHT', value=CAST(1 AS BIGINT)}, LAST_TRANSACTION_HASH=Column{typeInfo=BINARY VARYING(32), name='LAST_TRANSACTION_HASH', value=X'0000009d7817e1e5ba24a83a3d052befcede84ca391fa3911b69a5a99410b586'}, BALANCE=Column{typeInfo=BIGINT, name='BALANCE', value=-446744073709551616}}}'
	at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:47)
	at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:192)
	at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:175)
	at org.springframework.data.r2dbc.convert.MappingR2dbcConverter.read(MappingR2dbcConverter.java:110)
	at org.springframework.data.r2dbc.convert.EntityRowMapper.apply(EntityRowMapper.java:42)
	at org.springframework.data.r2dbc.convert.EntityRowMapper.apply(EntityRowMapper.java:29)
	at org.springframework.data.r2dbc.core.R2dbcEntityTemplate.lambda$getRowsFetchSpec$15(R2dbcEntityTemplate.java:804)
	at io.r2dbc.h2.H2Result.lambda$map$1(H2Result.java:103)
	at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:106)
	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79)
	at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:129)
	at reactor.core.publisher.FluxIterable$IterableSubscription.slowPath(FluxIterable.java:272)
	at reactor.core.publisher.FluxIterable$IterableSubscription.request(FluxIterable.java:230)
	at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:171)
	at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2304)
	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onSubscribe(FluxOnErrorResume.java:74)
	at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:96)
	at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:165)
	at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:87)
	at reactor.core.publisher.Flux.subscribe(Flux.java:8660)
	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.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:129)
	at reactor.core.publisher.FluxIterable$IterableSubscription.slowPath(FluxIterable.java:272)
	at reactor.core.publisher.FluxIterable$IterableSubscription.request(FluxIterable.java:230)
	at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:171)
	at reactor.core.publisher.FluxMap$MapSubscriber.request(FluxMap.java:164)
	at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.request(FluxOnAssembly.java:649)
	at reactor.core.publisher.FluxFlatMap$FlatMapMain.onSubscribe(FluxFlatMap.java:371)
	at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onSubscribe(FluxOnAssembly.java:633)
	at reactor.core.publisher.FluxMap$MapSubscriber.onSubscribe(FluxMap.java:92)
	at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:96)
	at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:165)
	at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:87)
	at reactor.core.publisher.Flux.subscribe(Flux.java:8660)
	at reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:200)
	at reactor.core.publisher.FluxFlatMap.subscribeOrReturn(FluxFlatMap.java:93)
	at reactor.core.publisher.Flux.subscribe(Flux.java:8646)
	at reactor.core.publisher.FluxUsingWhen$ResourceSubscriber.onNext(FluxUsingWhen.java:195)
	at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:122)
	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79)
	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79)
	at reactor.core.publisher.FluxRetry$RetrySubscriber.onNext(FluxRetry.java:87)
	at reactor.core.publisher.MonoFlatMap$FlatMapMain.secondComplete(MonoFlatMap.java:245)
	at reactor.core.publisher.MonoFlatMap$FlatMapInner.onNext(MonoFlatMap.java:305)
	at io.r2dbc.pool.MonoDiscardOnCancel$MonoDiscardOnCancelSubscriber.onNext(MonoDiscardOnCancel.java:92)
	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79)
	at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.complete(MonoIgnoreThen.java:292)
	at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onNext(MonoIgnoreThen.java:187)
	at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:236)
	at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onComplete(MonoIgnoreThen.java:203)
	at reactor.core.publisher.MonoIgnoreElements$IgnoreElementsSubscriber.onComplete(MonoIgnoreElements.java:89)
	at reactor.core.publisher.FluxHandle$HandleSubscriber.onComplete(FluxHandle.java:222)
	at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:85)
	at reactor.core.publisher.MonoCallable$MonoCallableSubscription.request(MonoCallable.java:159)
	at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2304)
	at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:2178)
	at reactor.core.publisher.MonoCallable.subscribe(MonoCallable.java:48)
	at reactor.core.publisher.Mono.subscribe(Mono.java:4444)
	at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:263)
	at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:51)
	at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
	at io.r2dbc.pool.MonoDiscardOnCancel.subscribe(MonoDiscardOnCancel.java:50)
	at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:165)
	at reactor.pool.AbstractPool$Borrower.deliver(AbstractPool.java:467)
	at reactor.pool.SimpleDequePool.lambda$drainLoop$8(SimpleDequePool.java:368)
	at reactor.core.scheduler.ImmediateScheduler.schedule(ImmediateScheduler.java:52)
	at reactor.pool.SimpleDequePool.drainLoop(SimpleDequePool.java:368)
	at reactor.pool.SimpleDequePool.pendingOffer(SimpleDequePool.java:598)
	at reactor.pool.SimpleDequePool.doAcquire(SimpleDequePool.java:294)
	at reactor.pool.AbstractPool$Borrower.request(AbstractPool.java:430)
	at reactor.core.publisher.MonoFlatMap$FlatMapMain.request(MonoFlatMap.java:194)
	at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2304)
	at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:2178)
	at reactor.core.publisher.MonoFlatMap$FlatMapMain.onSubscribe(MonoFlatMap.java:117)
	at reactor.pool.SimpleDequePool$QueueBorrowerMono.subscribe(SimpleDequePool.java:716)
	at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
	at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
	at reactor.core.publisher.FluxRetry$RetrySubscriber.resubscribe(FluxRetry.java:117)
	at reactor.core.publisher.MonoRetry.subscribeOrReturn(MonoRetry.java:50)
	at reactor.core.publisher.Mono.subscribe(Mono.java:4429)
	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:103)
	at reactor.core.publisher.MonoFlatMap$FlatMapMain.onError(MonoFlatMap.java:180)
	at reactor.core.publisher.FluxMap$MapSubscriber.onError(FluxMap.java:134)
	at reactor.core.publisher.Operators.error(Operators.java:198)
	at reactor.core.publisher.MonoError.subscribe(MonoError.java:53)
	at reactor.core.publisher.MonoDeferContextual.subscribe(MonoDeferContextual.java:55)
	at reactor.core.publisher.Mono.subscribe(Mono.java:4444)
	at reactor.core.publisher.FluxUsingWhen.subscribe(FluxUsingWhen.java:104)
	at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
	at reactor.core.publisher.MonoUsingWhen.subscribe(MonoUsingWhen.java:87)
	at reactor.core.publisher.Mono.subscribe(Mono.java:4444)
	at kotlinx.coroutines.reactive.AwaitKt.awaitOne(Await.kt:190)
	at kotlinx.coroutines.reactive.AwaitKt.awaitOne$default(Await.kt:183)
	at kotlinx.coroutines.reactive.AwaitKt.awaitSingleOrNull(Await.kt:141)
	at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvokeReactiveToSuspended(RepositoryMethodInvoker.java:184)
	at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:119)
	at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:516)
	at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:285)
	at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:628)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
	at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:168)
	at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:143)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
	at org.springframework.data.repository.core.support.MethodInvocationValidator.invoke(MethodInvocationValidator.java:94)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:218)
	at jdk.proxy2/jdk.proxy2.$Proxy127.findById(Unknown Source)
	at org.atto.node.transaction.TransactionStepDefinition$sendTransaction$1.invokeSuspend(TransactionStepDefinition.kt:29)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
	at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:284)
	at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:85)
	at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59)
	at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
	at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38)
	at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
	at org.atto.node.transaction.TransactionStepDefinition.sendTransaction(TransactionStepDefinition.kt:26)
	at ✽.send transaction 1 from THIS account to A account(file:///C:/Users/felip/dev/workspaces/node/atto-node/src/test/resources/features/transaction.feature:6)
Caused by: java.lang.IllegalArgumentException: Cannot decode value of type java.time.Instant
	at io.r2dbc.h2.codecs.DefaultCodecs.decode(DefaultCodecs.java:61)
	at io.r2dbc.h2.H2Row.get(H2Row.java:72)
	at org.atto.node.convertion.AccountDeserializerDBConverter.convert(AccountConverter.kt:46)
	at org.atto.node.convertion.AccountDeserializerDBConverter.convert(AccountConverter.kt:37)
	at org.springframework.core.convert.support.GenericConversionService$ConverterAdapter.convert(GenericConversionService.java:386)
	at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:41)
	at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:192)
	at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:175)
	at org.springframework.data.r2dbc.convert.MappingR2dbcConverter.read(MappingR2dbcConverter.java:110)
	at org.springframework.data.r2dbc.convert.EntityRowMapper.apply(EntityRowMapper.java:42)
	at org.springframework.data.r2dbc.convert.EntityRowMapper.apply(EntityRowMapper.java:29)
	at org.springframework.data.r2dbc.core.R2dbcEntityTemplate.lambda$getRowsFetchSpec$15(R2dbcEntityTemplate.java:804)
	at io.r2dbc.h2.H2Result.lambda$map$1(H2Result.java:103)
	at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:106)
	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79)
	at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:129)
	at reactor.core.publisher.FluxIterable$IterableSubscription.slowPath(FluxIterable.java:272)
	at reactor.core.publisher.FluxIterable$IterableSubscription.request(FluxIterable.java:230)
	at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:171)
	at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2304)
	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onSubscribe(FluxOnErrorResume.java:74)
	at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:96)
	at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:165)
	at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:87)
	at reactor.core.publisher.Flux.subscribe(Flux.java:8660)
	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.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:129)
	at reactor.core.publisher.FluxIterable$IterableSubscription.slowPath(FluxIterable.java:272)
	at reactor.core.publisher.FluxIterable$IterableSubscription.request(FluxIterable.java:230)
	at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:171)
	at reactor.core.publisher.FluxMap$MapSubscriber.request(FluxMap.java:164)
	at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.request(FluxOnAssembly.java:649)
	at reactor.core.publisher.FluxFlatMap$FlatMapMain.onSubscribe(FluxFlatMap.java:371)
	at reactor.core.publisher.FluxOnAssembly$OnAssemblySubscriber.onSubscribe(FluxOnAssembly.java:633)
	at reactor.core.publisher.FluxMap$MapSubscriber.onSubscribe(FluxMap.java:92)
	at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:96)
	at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:165)
	at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:87)
	at reactor.core.publisher.Flux.subscribe(Flux.java:8660)
	at reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:200)
	at reactor.core.publisher.FluxFlatMap.subscribeOrReturn(FluxFlatMap.java:93)
	at reactor.core.publisher.Flux.subscribe(Flux.java:8646)
	at reactor.core.publisher.FluxUsingWhen$ResourceSubscriber.onNext(FluxUsingWhen.java:195)
	at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:122)
	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79)
	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79)
	at reactor.core.publisher.FluxRetry$RetrySubscriber.onNext(FluxRetry.java:87)
	at reactor.core.publisher.MonoFlatMap$FlatMapMain.secondComplete(MonoFlatMap.java:245)
	at reactor.core.publisher.MonoFlatMap$FlatMapInner.onNext(MonoFlatMap.java:305)
	at io.r2dbc.pool.MonoDiscardOnCancel$MonoDiscardOnCancelSubscriber.onNext(MonoDiscardOnCancel.java:92)
	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onNext(FluxOnErrorResume.java:79)
	at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.complete(MonoIgnoreThen.java:292)
	at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onNext(MonoIgnoreThen.java:187)
	at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:236)
	at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.onComplete(MonoIgnoreThen.java:203)
	at reactor.core.publisher.MonoIgnoreElements$IgnoreElementsSubscriber.onComplete(MonoIgnoreElements.java:89)
	at reactor.core.publisher.FluxHandle$HandleSubscriber.onComplete(FluxHandle.java:222)
	at reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:85)
	at reactor.core.publisher.MonoCallable$MonoCallableSubscription.request(MonoCallable.java:159)
	at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2304)
	at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:2178)
	at reactor.core.publisher.MonoCallable.subscribe(MonoCallable.java:48)
	at reactor.core.publisher.Mono.subscribe(Mono.java:4444)
	at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.subscribeNext(MonoIgnoreThen.java:263)
	at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:51)
	at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
	at io.r2dbc.pool.MonoDiscardOnCancel.subscribe(MonoDiscardOnCancel.java:50)
	at reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:165)
	at reactor.pool.AbstractPool$Borrower.deliver(AbstractPool.java:467)
	at reactor.pool.SimpleDequePool.lambda$drainLoop$8(SimpleDequePool.java:368)
	at reactor.core.scheduler.ImmediateScheduler.schedule(ImmediateScheduler.java:52)
	at reactor.pool.SimpleDequePool.drainLoop(SimpleDequePool.java:368)
	at reactor.pool.SimpleDequePool.pendingOffer(SimpleDequePool.java:598)
	at reactor.pool.SimpleDequePool.doAcquire(SimpleDequePool.java:294)
	at reactor.pool.AbstractPool$Borrower.request(AbstractPool.java:430)
	at reactor.core.publisher.MonoFlatMap$FlatMapMain.request(MonoFlatMap.java:194)
	at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2304)
	at reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:2178)
	at reactor.core.publisher.MonoFlatMap$FlatMapMain.onSubscribe(MonoFlatMap.java:117)
	at reactor.pool.SimpleDequePool$QueueBorrowerMono.subscribe(SimpleDequePool.java:716)
	at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
	at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
	at reactor.core.publisher.FluxRetry$RetrySubscriber.resubscribe(FluxRetry.java:117)
	at reactor.core.publisher.MonoRetry.subscribeOrReturn(MonoRetry.java:50)
	at reactor.core.publisher.Mono.subscribe(Mono.java:4429)
	at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:103)
	at reactor.core.publisher.MonoFlatMap$FlatMapMain.onError(MonoFlatMap.java:180)
	at reactor.core.publisher.FluxMap$MapSubscriber.onError(FluxMap.java:134)
	at reactor.core.publisher.Operators.error(Operators.java:198)
	at reactor.core.publisher.MonoError.subscribe(MonoError.java:53)
	at reactor.core.publisher.MonoDeferContextual.subscribe(MonoDeferContextual.java:55)
	at reactor.core.publisher.Mono.subscribe(Mono.java:4444)
	at reactor.core.publisher.FluxUsingWhen.subscribe(FluxUsingWhen.java:104)
	at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
	at reactor.core.publisher.MonoUsingWhen.subscribe(MonoUsingWhen.java:87)
	at reactor.core.publisher.Mono.subscribe(Mono.java:4444)
	at kotlinx.coroutines.reactive.AwaitKt.awaitOne(Await.kt:190)
	at kotlinx.coroutines.reactive.AwaitKt.awaitOne$default(Await.kt:183)
	at kotlinx.coroutines.reactive.AwaitKt.awaitSingleOrNull(Await.kt:141)
	at org.springframework.data.repository.core.support.RepositoryMethodInvoker.doInvokeReactiveToSuspended(RepositoryMethodInvoker.java:184)
	at org.springframework.data.repository.core.support.RepositoryMethodInvoker.invoke(RepositoryMethodInvoker.java:119)
	at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:516)
	at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:285)
	at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:628)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
	at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:168)
	at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:143)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
	at org.springframework.data.repository.core.support.MethodInvocationValidator.invoke(MethodInvocationValidator.java:94)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:218)
	at jdk.proxy2/jdk.proxy2.$Proxy127.findById(Unknown Source)
	at org.atto.node.transaction.TransactionStepDefinition$sendTransaction$1.invokeSuspend(TransactionStepDefinition.kt:29)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
	at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:284)
	at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:85)
	at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59)
	at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
	at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38)
	at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
	at org.atto.node.transaction.TransactionStepDefinition.sendTransaction(TransactionStepDefinition.kt:26)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at io.cucumber.java.Invoker.doInvoke(Invoker.java:66)
	at io.cucumber.java.Invoker.invoke(Invoker.java:24)
	at io.cucumber.java.AbstractGlueDefinition.invokeMethod(AbstractGlueDefinition.java:47)
	at io.cucumber.java.JavaStepDefinition.execute(JavaStepDefinition.java:29)
	at io.cucumber.core.runner.CoreStepDefinition.execute(CoreStepDefinition.java:66)
	at io.cucumber.core.runner.PickleStepDefinitionMatch.runStep(PickleStepDefinitionMatch.java:63)
	at io.cucumber.core.runner.ExecutionMode$1.execute(ExecutionMode.java:10)
	at io.cucumber.core.runner.TestStep.executeStep(TestStep.java:85)
	at io.cucumber.core.runner.TestStep.run(TestStep.java:57)
	at io.cucumber.core.runner.PickleStepTestStep.run(PickleStepTestStep.java:51)
	at io.cucumber.core.runner.TestCase.run(TestCase.java:84)
	at io.cucumber.core.runner.Runner.runPickle(Runner.java:75)
	at io.cucumber.core.runtime.Runtime.lambda$executePickle$6(Runtime.java:128)
	at io.cucumber.core.runtime.CucumberExecutionContext.lambda$runTestCase$5(CucumberExecutionContext.java:129)
	at io.cucumber.core.runtime.RethrowingThrowableCollector.executeAndThrow(RethrowingThrowableCollector.java:23)
	at io.cucumber.core.runtime.CucumberExecutionContext.runTestCase(CucumberExecutionContext.java:129)
	at io.cucumber.core.runtime.Runtime.lambda$executePickle$7(Runtime.java:128)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at io.cucumber.core.runtime.Runtime$SameThreadExecutorService.execute(Runtime.java:249)
	at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:123)
	at io.cucumber.core.runtime.Runtime.lambda$runFeatures$3(Runtime.java:110)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.stream.SliceOps$1$1.accept(SliceOps.java:200)
	at java.base/java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1602)
	at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:129)
	at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
	at io.cucumber.core.runtime.Runtime.runFeatures(Runtime.java:111)
	at io.cucumber.core.runtime.Runtime.lambda$run$0(Runtime.java:82)
	at io.cucumber.core.runtime.Runtime.execute(Runtime.java:94)
	at io.cucumber.core.runtime.Runtime.run(Runtime.java:80)
	at io.cucumber.core.cli.Main.run(Main.java:87)
	at io.cucumber.core.cli.Main.main(Main.java:30)

Table schema

Input Code
CREATE TABLE account
(
    public_key                 VARBINARY(32) PRIMARY KEY,
    version                    SMALLINT UNSIGNED                                               NOT NULl,
    height                     BIGINT UNSIGNED                                                 NOT NULL,
    balance                    BIGINT UNSIGNED                                                 NOT NULL,
    last_transaction_hash      VARBINARY(32)                                                   NOT NULl,
    last_transaction_timestamp TIMESTAMP                                                       NOT NULL,
    representative             VARBINARY(32)                                                   NOT NULL,

    persisted_at               TIMESTAMP DEFAULT CURRENT_TIMESTAMP                             NOT NULL,
    updated_at                 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL
);

Steps to reproduce

Input Code
@Component
class AccountDeserializerDBConverter : DBConverter<Row, Account> {
    override fun convert(row: Row): Account {
        return Account(
            publicKey = AttoPublicKey(row.get("public_key", ByteArray::class.java)!!),
            version = row.get("version", Short::class.javaObjectType)!!.toUShort(),
            height = row.get("height", Long::class.javaObjectType)!!.toULong(),
            balance = AttoAmount(row.get("balance", Long::class.javaObjectType)!!.toULong()),
            lastTransactionHash = AttoHash(row.get("last_transaction_hash", ByteArray::class.java)!!),
            lastTransactionTimestamp = row.get("last_transaction_timestamp", Instant::class.java)!!,
            representative = AttoPublicKey(row.get("representative", ByteArray::class.java)!!),
            persistedAt = row.get("persisted_at", Instant::class.java)!!,
            updatedAt = row.get("updated_at", Instant::class.java)!!,
        )
    }
}

Expected behavior/code

Decode TIMESTAMP into Instant

Possible Solution

Additional context

@katzyn
Copy link

katzyn commented Dec 12, 2022

however JDBC implementation seems happy with that

TIMESTAMP is a wrong data type for Instant values, there is no exact mapping between them.
https://h2database.com/html/datatypes.html#timestamp_type

H2's own JDBC driver on attempt to read TIMESTAMP as Instant performs an additional automatic conversion to TIMESTAMP(9) WITH TIME ZONE with current time zone of the session and only then converts produced TIMESTAMP(9) WITH TIME ZONE value to java.time.Instant.
https://h2database.com/html/datatypes.html#timestamp_with_time_zone_type

But R2DBC is more restrictive than JDBC, it doesn't perform conversions between SQL data types.

@rotilho
Copy link
Author

rotilho commented Dec 12, 2022

Doesn't it defeat the purpose of h2? I normally use h2 strictly for testing, and I believe most people use it in a similar setup.

The suggestion to use TIMESTAMP(9) WITH TIME ZONE will unfortunately fail in Postgres (due to TIMESTAMP(9)) and MySQL (due to WITH TIME ZONE), essentially making it unusable for testing if you want to use Instant in 2 major db.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants