#465 - Convert bind values for String-based queries to their native type.
We now invoke the converter for query arguments of String-based queries (using the Query annotation or named queries) to convert the value into a type that can be used by the driver. Previously all values were passed-thru which caused for e.g. enums to pass-thru these to the driver and the driver encode failed.
This commit is contained in:
@@ -33,6 +33,9 @@ import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.projection.ProjectionFactory;
|
||||
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
|
||||
import org.springframework.data.r2dbc.convert.MappingR2dbcConverter;
|
||||
import org.springframework.data.r2dbc.core.DefaultReactiveDataAccessStrategy;
|
||||
import org.springframework.data.r2dbc.core.ReactiveDataAccessStrategy;
|
||||
import org.springframework.data.r2dbc.dialect.PostgresDialect;
|
||||
import org.springframework.data.r2dbc.mapping.R2dbcMappingContext;
|
||||
import org.springframework.data.r2dbc.repository.Query;
|
||||
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
|
||||
@@ -62,6 +65,7 @@ public class StringBasedR2dbcQueryUnitTests {
|
||||
|
||||
private RelationalMappingContext mappingContext;
|
||||
private MappingR2dbcConverter converter;
|
||||
private ReactiveDataAccessStrategy accessStrategy;
|
||||
private ProjectionFactory factory;
|
||||
private RepositoryMetadata metadata;
|
||||
|
||||
@@ -70,6 +74,7 @@ public class StringBasedR2dbcQueryUnitTests {
|
||||
|
||||
this.mappingContext = new R2dbcMappingContext();
|
||||
this.converter = new MappingR2dbcConverter(this.mappingContext);
|
||||
this.accessStrategy = new DefaultReactiveDataAccessStrategy(PostgresDialect.INSTANCE, converter);
|
||||
this.metadata = AbstractRepositoryMetadata.getMetadata(SampleRepository.class);
|
||||
this.factory = new SpelAwareProxyProjectionFactory();
|
||||
|
||||
@@ -240,13 +245,26 @@ public class StringBasedR2dbcQueryUnitTests {
|
||||
verifyNoMoreInteractions(bindSpec);
|
||||
}
|
||||
|
||||
@Test // gh-465
|
||||
void translatesEnumToDatabaseValue() {
|
||||
|
||||
StringBasedR2dbcQuery query = getQueryMethod("queryWithEnum", MyEnum.class);
|
||||
R2dbcParameterAccessor accessor = new R2dbcParameterAccessor(query.getQueryMethod(), MyEnum.INSTANCE);
|
||||
|
||||
BindableQuery stringQuery = query.createQuery(accessor).block();
|
||||
assertThat(stringQuery.bind(bindSpec)).isNotNull();
|
||||
|
||||
verify(bindSpec).bind(0, "INSTANCE");
|
||||
verifyNoMoreInteractions(bindSpec);
|
||||
}
|
||||
|
||||
private StringBasedR2dbcQuery getQueryMethod(String name, Class<?>... args) {
|
||||
|
||||
Method method = ReflectionUtils.findMethod(SampleRepository.class, name, args);
|
||||
|
||||
R2dbcQueryMethod queryMethod = new R2dbcQueryMethod(method, metadata, factory, converter.getMappingContext());
|
||||
|
||||
return new StringBasedR2dbcQuery(queryMethod, databaseClient, converter, PARSER,
|
||||
return new StringBasedR2dbcQuery(queryMethod, databaseClient, converter, accessStrategy, PARSER,
|
||||
ReactiveQueryMethodEvaluationContextProvider.DEFAULT);
|
||||
}
|
||||
|
||||
@@ -285,6 +303,9 @@ public class StringBasedR2dbcQueryUnitTests {
|
||||
|
||||
@Query("SELECT * FROM person WHERE lastname = :name")
|
||||
Person queryWithUnusedParameter(String name, Sort unused);
|
||||
|
||||
@Query("SELECT * FROM person WHERE lastname = :name")
|
||||
Person queryWithEnum(MyEnum myEnum);
|
||||
}
|
||||
|
||||
static class Person {
|
||||
@@ -299,4 +320,8 @@ public class StringBasedR2dbcQueryUnitTests {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
enum MyEnum {
|
||||
INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user