From 569cd9cad26bcc9ceb789d3769eded14a726f48e Mon Sep 17 00:00:00 2001 From: Mohammadali Jalalkamali Date: Sat, 6 Dec 2025 15:48:13 +0330 Subject: [PATCH] GH-2188 - Preserve JDBCType.OTHER in string-based queries Signed-off-by: Mohammadali Jalalkamali --- .../query/StringBasedJdbcQuery.java | 6 ++--- .../query/StringBasedJdbcQueryUnitTests.java | 26 +++++++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQuery.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQuery.java index e724deeae2..da233fc365 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQuery.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQuery.java @@ -261,10 +261,10 @@ private MapSqlParameterSource bindParameters(RelationalParameterAccessor accesso JdbcValue jdbcValue = JdbcValueBindUtil.getBindValue(converter, value, parameter); SQLType jdbcType = jdbcValue.getJdbcType(); - if (jdbcType == JDBCType.OTHER) { - parameters.addValue(parameterName, jdbcValue.getValue()); - } else { + if (jdbcType != null) { parameters.addValue(parameterName, jdbcValue.getValue(), jdbcType.getVendorTypeNumber()); + } else { + parameters.addValue(parameterName, jdbcValue.getValue()); } } diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQueryUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQueryUnitTests.java index 56e895fafd..d98621ac0f 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQueryUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQueryUnitTests.java @@ -416,6 +416,18 @@ void spelCanBeUsedInsideQueries() { assertThat(paramSource.getValue().getValue("__$synthetic$__2")).isEqualTo("test-value2"); } + @Test // GH-2188 + void shouldPreserveJdbcTypeOtherFromJdbcValueInStringBasedQuery() { + + SqlParameterSource parameterSource = forMethod("findByCustomValue", Direction.class) + .withCustomConverters(DirectionToOtherJdbcTypeConverter.INSTANCE) + .withArguments(Direction.LEFT) + .extractParameterSource(); + + assertThat(parameterSource.getSqlType("value")) + .isEqualTo(JDBCType.OTHER.getVendorTypeNumber()); + } + QueryFixture forMethod(String name, Class... paramTypes) { return new QueryFixture(createMethod(name, paramTypes)); } @@ -562,6 +574,9 @@ interface MyRepository extends Repository { @Lock(value = LockMode.PESSIMISTIC_READ) @Query("SELECT * FROM person WHERE id = :id") DummyEntity unsupportedWithLock(Long id); + + @Query(value = "some sql statement") // GH-2188 + List findByCustomValue(@Param("value") Direction value); } private static class CustomRowMapper implements RowMapper { @@ -655,6 +670,17 @@ public String convert(ListContainer source) { } } + @WritingConverter // GH-2188 + enum DirectionToOtherJdbcTypeConverter implements Converter { + + INSTANCE; + + @Override + public JdbcValue convert(Direction source) { + return JdbcValue.of(source.name(), JDBCType.OTHER); + } + } + private static class DummyEntity { private final Long id;