es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

El uso de $1 en la @Query genera una excepción: No se puede codificar el parámetro de tipo org.springframework.r2dbc.core.Parameter.

Estoy usando R2DBC en mi proyecto. Después de actualizar a Spring Boot de 2.5.* a 2.6.1, mi consulta:

@Query("SELECT EXISTS(SELECT 1 FROM some_link links WHERE links.data_id = $1 AND links.some_id != links.source_id)")
fun existsByDataIdAndLocked(dataId: UUID): Mono<boolean>

Arroja una excepción:

Suppressed: java.lang.IllegalArgumentException: Cannot encode parameter of type org.springframework.r2dbc.core.Parameter
    at io.r2dbc.postgresql.codec.DefaultCodecs.encode(DefaultCodecs.java:192)
    at io.r2dbc.postgresql.ExtendedQueryPostgresqlStatement.bind(ExtendedQueryPostgresqlStatement.java:89)
    at io.r2dbc.postgresql.ExtendedQueryPostgresqlStatement.bind(ExtendedQueryPostgresqlStatement.java:47)
    at org.springframework.r2dbc.core.DefaultDatabaseClient$StatementWrapper.bind(DefaultDatabaseClient.java:544)
    at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:684)
    at org.springframework.data.r2dbc.repository.query.StringBasedR2dbcQuery$ExpandedQuery.bindTo(StringBasedR2dbcQuery.java:227)
    at org.springframework.r2dbc.core.DefaultDatabaseClient$DefaultGenericExecuteSpec.lambda$execute$2(DefaultDatabaseClient.java:334)
    at org.springframework.r2dbc.core.DefaultDatabaseClient$DefaultGenericExecuteSpec.lambda$execute$3(DefaultDatabaseClient.java:374)
    at org.springframework.r2dbc.core.ConnectionFunction.apply(ConnectionFunction.java:46)
    at org.springframework.r2dbc.core.ConnectionFunction.apply(ConnectionFunction.java:31)
    at org.springframework.r2dbc.core.DefaultFetchSpec.lambda$all$2(DefaultFetchSpec.java:88)
    at org.springframework.r2dbc.core.ConnectionFunction.apply(ConnectionFunction.java:46)
    at org.springframework.r2dbc.core.ConnectionFunction.apply(ConnectionFunction.java:31)
    at org.springframework.r2dbc.core.DefaultDatabaseClient.lambda$inConnectionMany$6(DefaultDatabaseClient.java:138)
    at reactor.core.publisher.FluxUsingWhen.deriveFluxFromResource(FluxUsingWhen.java:119)
    at reactor.core.publisher.FluxUsingWhen.access$000(FluxUsingWhen.java:53)
    at reactor.core.publisher.FluxUsingWhen$ResourceSubscriber.onNext(FluxUsingWhen.java:194)
    ... 172 more

Una vez que cambio <code>$1</code> en la consulta por <code>:dataId</code>, entonces funciona.

¿Por qué sucede esto? Según la documentación, ambos son válidos.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    La diferencia entre $1 y :dataId en la consulta es que $1 es un marcador de posición para el primer parámetro en la firma del método, mientras que :dataId es un parámetro con nombre que se mapea al parámetro en la firma del método con el mismo nombre.

    En Spring Data R2DBC, puedes usar marcadores de posición ordinales ($1, $2, etc.) o parámetros con nombres (:nombreParametro) en consultas SQL. Sin embargo, al usar parámetros con nombres, debes asegurarte de que los nombres de parámetros utilizados en la consulta coincidan con los nombres de los parámetros utilizados en la firma del método.

    El error que estás viendo indica que el parámetro no pudo ser codificado correctamente. Esto podría deberse a una diferencia entre el nombre de parámetro utilizado en la consulta ($1) y el nombre de parámetro utilizado en la firma del método (dataId).

    Al cambiar la consulta de $1 a :dataId, estás utilizando un parámetro con nombre que coincide con el nombre del parámetro en la firma del método, y esto permite que Spring Data R2DBC mapee correctamente el parámetro al ejecutar la consulta.

Comments are closed.