From 00f4a61b82dbcc80195ad9c993bee4b20c5af9f3 Mon Sep 17 00:00:00 2001 From: Jens Schauder Date: Thu, 10 Apr 2025 13:22:51 +0200 Subject: [PATCH] Polishing. Formatting. Added a test. Original pull request #2023 See #2008 --- .../query/StringBasedJdbcQuery.java | 3 +- .../query/StringBasedJdbcQueryUnitTests.java | 31 +++++++++++++++---- 2 files changed, 27 insertions(+), 7 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 3219917d6..6f57149d7 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 @@ -73,7 +73,7 @@ import org.springframework.util.ObjectUtils; public class StringBasedJdbcQuery extends AbstractJdbcQuery { private static final String PARAMETER_NEEDS_TO_BE_NAMED = "For queries with named parameters you need to provide names for method parameters; Use @Param for query method parameters, or use the javac flag -parameters"; - private final static String LOCKING_IS_NOT_SUPPORTED = "Currently, @Lock is supported only on derived queries. In other words, for queries created with @Query, the locking condition specified with @Lock does nothing. Offending method: "; + private static final String LOCKING_IS_NOT_SUPPORTED = "Currently, @Lock is supported only on derived queries. In other words, for queries created with @Query, the locking condition specified with @Lock does nothing. Offending method: "; private final JdbcConverter converter; private final RowMapperFactory rowMapperFactory; private final ValueExpressionQueryRewriter.ParsedQuery parsedQuery; @@ -457,6 +457,7 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery { @Nullable static Constructor findPrimaryConstructor(Class clazz) { + try { return clazz.getDeclaredConstructor(); } catch (NoSuchMethodException ex) { 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 c0d9cd5bf..9d222e653 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 @@ -53,6 +53,8 @@ import org.springframework.data.jdbc.core.mapping.JdbcValue; import org.springframework.data.jdbc.support.JdbcUtil; import org.springframework.data.projection.SpelAwareProxyProjectionFactory; import org.springframework.data.relational.core.mapping.RelationalMappingContext; +import org.springframework.data.relational.core.sql.LockMode; +import org.springframework.data.relational.repository.Lock; import org.springframework.data.repository.Repository; import org.springframework.data.repository.core.support.DefaultRepositoryMetadata; import org.springframework.data.repository.core.support.PropertiesBasedNamedQueries; @@ -252,7 +254,7 @@ class StringBasedJdbcQueryUnitTests { JdbcQueryMethod queryMethod = createMethod("sliceAll", Pageable.class); assertThatThrownBy( - () -> new StringBasedJdbcQuery(queryMethod, operations, result -> defaultRowMapper, converter, delegate)) + () -> new StringBasedJdbcQuery(queryMethod, operations, result -> defaultRowMapper, converter, delegate)) .isInstanceOf(UnsupportedOperationException.class) .hasMessageContaining("Slice queries are not supported using string-based queries"); } @@ -278,6 +280,16 @@ class StringBasedJdbcQueryUnitTests { .isInstanceOf(UnsupportedOperationException.class); } + @Test // GH-2023 + void lockNotSupported() { + + JdbcQueryMethod queryMethod = createMethod("unsupportedWithLock", Long.class); + + assertThatThrownBy( + () -> new StringBasedJdbcQuery(queryMethod, operations, result -> defaultRowMapper, converter, delegate)) + .isInstanceOf(UnsupportedOperationException.class); + } + @Test // GH-1212 void convertsEnumCollectionParameterIntoStringCollectionParameter() { @@ -355,10 +367,12 @@ class StringBasedJdbcQueryUnitTests { List list = new ArrayList<>(); list.add(new MyEvaluationContextProvider()); - QueryMethodValueEvaluationContextAccessor accessor = new QueryMethodValueEvaluationContextAccessor(new StandardEnvironment(), list); + QueryMethodValueEvaluationContextAccessor accessor = new QueryMethodValueEvaluationContextAccessor( + new StandardEnvironment(), list); this.delegate = new ValueExpressionDelegate(accessor, ValueExpressionParser.create()); - StringBasedJdbcQuery sut = new StringBasedJdbcQuery(queryMethod, operations, result -> defaultRowMapper, converter, delegate); + StringBasedJdbcQuery sut = new StringBasedJdbcQuery(queryMethod, operations, result -> defaultRowMapper, converter, + delegate); ArgumentCaptor paramSource = ArgumentCaptor.forClass(SqlParameterSource.class); ArgumentCaptor query = ArgumentCaptor.forClass(String.class); @@ -401,8 +415,8 @@ class StringBasedJdbcQueryUnitTests { mock(RelationResolver.class)) : this.converter; - StringBasedJdbcQuery query = new StringBasedJdbcQuery(method.getDeclaredQuery(), method, operations, result -> mock(RowMapper.class), - converter, delegate); + StringBasedJdbcQuery query = new StringBasedJdbcQuery(method.getDeclaredQuery(), method, operations, + result -> mock(RowMapper.class), converter, delegate); query.execute(arguments); @@ -438,7 +452,8 @@ class StringBasedJdbcQueryUnitTests { } private StringBasedJdbcQuery createQuery(JdbcQueryMethod queryMethod, String preparedReference, Object value) { - return new StringBasedJdbcQuery(queryMethod, operations, new StubRowMapperFactory(preparedReference, value), converter, delegate); + return new StringBasedJdbcQuery(queryMethod, operations, new StubRowMapperFactory(preparedReference, value), + converter, delegate); } interface MyRepository extends Repository { @@ -505,6 +520,10 @@ class StringBasedJdbcQueryUnitTests { @Query("select count(1) from person where (firstname, lastname) in (:tuples)") Object findByListOfTuples(@Param("tuples") List tuples); + + @Lock(value = LockMode.PESSIMISTIC_READ) + @Query("SELECT * FROM person WHERE id = :id") + DummyEntity unsupportedWithLock(Long id); } private static class CustomRowMapper implements RowMapper {