0

拥有这个实体:

data class Avatar(
  // id is generated by postgres default value
  @Id
  val id: UUID? = null,
  val userId: Long,
  var avatar: ByteArray,
)

这个架构:

CREATE TABLE avatar (
    id              uuid    PRIMARY KEY DEFAULT uuid_generate_v4(),
    user_id         bigint  NOT NULL UNIQUE REFERENCES users(id) ON DELETE CASCADE,
    avatar          bytea   NOT NULL
);

这个存储库:

@Repository
interface AvatarRepository : CoroutineCrudRepository<Avatar, UUID> {
  @Query("SELECT user_id FROM avatar WHERE id = :avatarId")
  suspend fun findUserIdById(avatarId: UUID): Long?
}

我可以保存和获取实体,但是在删除时@Query我不能使用findUserIdById来仅加载userId属性

internal class AvatarRepositoryTest  : RepositoryTest() {
  @Autowired
  private lateinit var avatarRepository: AvatarRepository

  @Test
  fun findUserIdById() {
    setupDevData()
    val expectedUserId = 1L
    val bytes = byteArrayOf(0x2E)
    runBlocking {
      val stored = avatarRepository.save(Avatar(
        id = null,
        userId = expectedUserId,
        avatar = bytes,
      ))
      assertThat(stored.id).isNotNull
     
      // ----------> the next line fails WITHOUT THE @Query("...") annotation <----------
      val actual = avatarRepository.findUserIdById(stored.id!!)

      assertThat(actual).isEqualTo(expectedUserId)
    }
  }
}

导致此错误:

Failed to convert from type [io.r2dbc.postgresql.PostgresqlRow] to type [java.lang.Long] for value 'PostgresqlRow{context=ConnectionContext{client=io.r2dbc.postgresql.client.ReactorNettyClient@8e0755, codecs=io.r2dbc.postgresql.codec.DefaultCodecs@7fecd70a, connection=PostgresqlConnection{client=io.r2dbc.postgresql.client.ReactorNettyClient@8e0755, codecs=io.r2dbc.postgresql.codec.DefaultCodecs@7fecd70a}, configuration=PostgresqlConnectionConfiguration{applicationName='r2dbc-postgresql', autodetectExtensions='true', compatibilityMode=false, connectTimeout=null, database='db', extensions=[], fetchSize=io.r2dbc.postgresql.PostgresqlConnectionConfiguration$Builder$$Lambda$862/0x000000080107d440@6974166c, forceBinary='false', host='localhost', loopResources='null', options='{}', password='****', port=49416, preferAttachedBuffers=false, socket=null, tcpKeepAlive=false, tcpNoDelay=true, username='test'}, portalNameSupplier=io.r2dbc.postgresql.DefaultPortalNameSupplier@6bfe38c7, statementCache=IndefiniteStatementCache{cache={SELECT avatar.id, avatar.user_id, avatar.avatar FROM avatar WHERE avatar.id = $1={[I@1b3a3e42=S_0}}, counter=1}}, columns=[Field{column=1, dataType=2950, dataTypeModifier=-1, dataTypeSize=16, format=FORMAT_TEXT, name='id', table=16419}, Field{column=2, dataType=20, dataTypeModifier=-1, dataTypeSize=8, format=FORMAT_TEXT, name='user_id', table=16419}, Field{column=3, dataType=17, dataTypeModifier=-1, dataTypeSize=-1, format=FORMAT_TEXT, name='avatar', table=16419}], isReleased=false}'; nested exception is java.lang.ClassCastException: class java.util.UUID cannot be cast to class java.lang.Number (java.util.UUID and java.lang.Number are in module java.base of loader 'bootstrap')
org.springframework.core.convert.ConversionFailedException: Failed to convert from type [io.r2dbc.postgresql.PostgresqlRow] to type [java.lang.Long] for value 'PostgresqlRow{context=ConnectionContext{client=io.r2dbc.postgresql.client.ReactorNettyClient@8e0755, codecs=io.r2dbc.postgresql.codec.DefaultCodecs@7fecd70a, connection=PostgresqlConnection{client=io.r2dbc.postgresql.client.ReactorNettyClient@8e0755, codecs=io.r2dbc.postgresql.codec.DefaultCodecs@7fecd70a}, configuration=PostgresqlConnectionConfiguration{applicationName='r2dbc-postgresql', autodetectExtensions='true', compatibilityMode=false, connectTimeout=null, database='db', extensions=[], fetchSize=io.r2dbc.postgresql.PostgresqlConnectionConfiguration$Builder$$Lambda$862/0x000000080107d440@6974166c, forceBinary='false', host='localhost', loopResources='null', options='{}', password='****', port=49416, preferAttachedBuffers=false, socket=null, tcpKeepAlive=false, tcpNoDelay=true, username='test'}, portalNameSupplier=io.r2dbc.postgresql.DefaultPortalNameSupplier@6bfe38c7, statementCache=IndefiniteStatementCache{cache={SELECT avatar.id, avatar.user_id, avatar.avatar FROM avatar WHERE avatar.id = $1={[I@1b3a3e42=S_0}}, counter=1}}, columns=[Field{column=1, dataType=2950, dataTypeModifier=-1, dataTypeSize=16, format=FORMAT_TEXT, name='id', table=16419}, Field{column=2, dataType=20, dataTypeModifier=-1, dataTypeSize=8, format=FORMAT_TEXT, name='user_id', table=16419}, Field{column=3, dataType=17, dataTypeModifier=-1, dataTypeSize=-1, format=FORMAT_TEXT, name='avatar', table=16419}], isReleased=false}'; nested exception is java.lang.ClassCastException: class java.util.UUID cannot be cast to class java.lang.Number (java.util.UUID and java.lang.Number are in module java.base of loader 'bootstrap')
    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:116)
    at org.springframework.data.r2dbc.convert.EntityRowMapper.apply(EntityRowMapper.java:46)
    at org.springframework.data.r2dbc.repository.query.AbstractR2dbcQuery.lambda$executeQuery$2(AbstractR2dbcQuery.java:111)
    at io.r2dbc.postgresql.PostgresqlResult.lambda$map$1(PostgresqlResult.java:111)
    at reactor.core.publisher.FluxHandle$HandleSubscriber.onNext(FluxHandle.java:102)
    at reactor.core.publisher.MonoFlatMapMany$FlatMapManyInner.onNext(MonoFlatMapMany.java:250)
    at org.springframework.security.test.context.support.ReactorContextTestExecutionListener$DelegateTestExecutionListener$SecuritySubContext.onNext(ReactorContextTestExecutionListener.java:120)
    at reactor.core.publisher.FluxHandleFuseable$HandleFuseableSubscriber.onNext(FluxHandleFuseable.java:184)
    at reactor.core.publisher.FluxFilterFuseable$FilterFuseableConditionalSubscriber.onNext(FluxFilterFuseable.java:337)
    at reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.onNext(FluxContextWrite.java:107)
    at reactor.core.publisher.FluxPeekFuseable$PeekConditionalSubscriber.onNext(FluxPeekFuseable.java:854)
    at io.r2dbc.postgresql.util.FluxDiscardOnCancel$FluxDiscardOnCancelSubscriber.onNext(FluxDiscardOnCancel.java:86)
    at reactor.core.publisher.FluxCreate$BufferAsyncSink.drain(FluxCreate.java:793)
    at reactor.core.publisher.FluxCreate$BufferAsyncSink.next(FluxCreate.java:718)
    at reactor.core.publisher.FluxCreate$SerializedFluxSink.next(FluxCreate.java:154)
    at io.r2dbc.postgresql.client.ReactorNettyClient$Conversation.emit(ReactorNettyClient.java:735)
    at io.r2dbc.postgresql.client.ReactorNettyClient$BackendMessageSubscriber.emit(ReactorNettyClient.java:986)
    at io.r2dbc.postgresql.client.ReactorNettyClient$BackendMessageSubscriber.onNext(ReactorNettyClient.java:860)
    at io.r2dbc.postgresql.client.ReactorNettyClient$BackendMessageSubscriber.onNext(ReactorNettyClient.java:767)
    at reactor.core.publisher.FluxHandle$HandleSubscriber.onNext(FluxHandle.java:118)
    at reactor.core.publisher.FluxPeekFuseable$PeekConditionalSubscriber.onNext(FluxPeekFuseable.java:854)
    at reactor.core.publisher.FluxMap$MapConditionalSubscriber.onNext(FluxMap.java:220)
    at reactor.core.publisher.FluxMap$MapConditionalSubscriber.onNext(FluxMap.java:220)
    at reactor.netty.channel.FluxReceive.drainReceiver(FluxReceive.java:280)
    at reactor.netty.channel.FluxReceive.onInboundNext(FluxReceive.java:389)
    at reactor.netty.channel.ChannelOperations.onInboundNext(ChannelOperations.java:401)
    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.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324)
    at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:311)
    at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:432)
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276)
    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.epoll.AbstractEpollStreamChannel$EpollStreamUnsafe.epollInReady(AbstractEpollStreamChannel.java:795)
    at io.netty.channel.epoll.EpollEventLoop.processReady(EpollEventLoop.java:480)
    at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:378)
    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:832)
Caused by: java.lang.ClassCastException: class java.util.UUID cannot be cast to class java.lang.Number (java.util.UUID and java.lang.Number are in module java.base of loader 'bootstrap')
    at org.springframework.data.r2dbc.convert.R2dbcConverters$RowToNumberConverterFactory$RowToNumber.convert(R2dbcConverters.java:191)
    at org.springframework.data.r2dbc.convert.R2dbcConverters$RowToNumberConverterFactory$RowToNumber.convert(R2dbcConverters.java:178)
    at org.springframework.core.convert.support.GenericConversionService$ConverterFactoryAdapter.convert(GenericConversionService.java:437)
    at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:41)
    ... 50 more

我以为这是支持?

4

0 回答 0