Skip to content

Commit bb1e62f

Browse files
committed
Consider io.r2dbc.spi.Parameter as simple type.
We now consider R2DBC's Parameter as simple type to avoid entity handling. Closes #1696
1 parent cc43be8 commit bb1e62f

File tree

2 files changed

+47
-4
lines changed

2 files changed

+47
-4
lines changed

spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/mapping/R2dbcSimpleTypeHolder.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import io.r2dbc.spi.Blob;
1919
import io.r2dbc.spi.Clob;
20+
import io.r2dbc.spi.Parameter;
2021
import io.r2dbc.spi.Row;
2122

2223
import java.math.BigDecimal;
@@ -42,7 +43,7 @@ public class R2dbcSimpleTypeHolder extends SimpleTypeHolder {
4243
*/
4344
public static final Set<Class<?>> R2DBC_SIMPLE_TYPES = Collections
4445
.unmodifiableSet(new HashSet<>(Arrays.asList(OutboundRow.class, Row.class, BigInteger.class, BigDecimal.class,
45-
UUID.class, Blob.class, Clob.class, ByteBuffer.class)));
46+
UUID.class, Blob.class, Clob.class, ByteBuffer.class, Parameter.class)));
4647

4748
public static final SimpleTypeHolder HOLDER = new R2dbcSimpleTypeHolder();
4849

spring-data-r2dbc/src/test/java/org/springframework/data/r2dbc/core/R2dbcEntityTemplateUnitTests.java

+45-3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import static org.mockito.Mockito.*;
2020
import static org.springframework.data.relational.core.query.Criteria.*;
2121

22+
import io.r2dbc.spi.Parameters;
2223
import io.r2dbc.spi.R2dbcType;
2324
import io.r2dbc.spi.test.MockColumnMetadata;
2425
import io.r2dbc.spi.test.MockResult;
@@ -35,6 +36,7 @@
3536
import org.junit.jupiter.api.BeforeEach;
3637
import org.junit.jupiter.api.Test;
3738
import org.springframework.beans.factory.ObjectFactory;
39+
import org.springframework.core.convert.converter.Converter;
3840
import org.springframework.data.annotation.CreatedDate;
3941
import org.springframework.data.annotation.Id;
4042
import org.springframework.data.annotation.LastModifiedDate;
@@ -43,8 +45,11 @@
4345
import org.springframework.data.domain.Sort;
4446
import org.springframework.data.mapping.callback.ReactiveEntityCallbacks;
4547
import org.springframework.data.mapping.context.PersistentEntities;
48+
import org.springframework.data.r2dbc.convert.MappingR2dbcConverter;
49+
import org.springframework.data.r2dbc.convert.R2dbcCustomConversions;
4650
import org.springframework.data.r2dbc.dialect.PostgresDialect;
4751
import org.springframework.data.r2dbc.mapping.OutboundRow;
52+
import org.springframework.data.r2dbc.mapping.R2dbcMappingContext;
4853
import org.springframework.data.r2dbc.mapping.event.AfterConvertCallback;
4954
import org.springframework.data.r2dbc.mapping.event.AfterSaveCallback;
5055
import org.springframework.data.r2dbc.mapping.event.BeforeConvertCallback;
@@ -82,7 +87,11 @@ void before() {
8287
recorder = StatementRecorder.newInstance();
8388
client = DatabaseClient.builder().connectionFactory(recorder)
8489
.bindMarkers(PostgresDialect.INSTANCE.getBindMarkersFactory()).build();
85-
entityTemplate = new R2dbcEntityTemplate(client, PostgresDialect.INSTANCE);
90+
91+
R2dbcCustomConversions conversions = R2dbcCustomConversions.of(PostgresDialect.INSTANCE, new MoneyConverter());
92+
93+
entityTemplate = new R2dbcEntityTemplate(client, PostgresDialect.INSTANCE,
94+
new MappingR2dbcConverter(new R2dbcMappingContext(), conversions));
8695
}
8796

8897
@Test // gh-220
@@ -147,7 +156,6 @@ void shouldProjectEntityUsingInheritedInterface() {
147156
assertThat(actual).isInstanceOf(Person.class);
148157
}).verifyComplete();
149158

150-
151159
StatementRecorder.RecordedStatement statement = recorder.getCreatedStatement(s -> s.startsWith("SELECT"));
152160
assertThat(statement.getSql()).isEqualTo("SELECT foo.* FROM foo WHERE foo.THE_NAME = $1");
153161
}
@@ -584,10 +592,29 @@ void updateExcludesInsertOnlyColumns() {
584592
Parameter.from(23L));
585593
}
586594

595+
@Test // GH-1696
596+
void shouldConsiderParameterConverter() {
597+
598+
MockRowMetadata metadata = MockRowMetadata.builder().build();
599+
MockResult result = MockResult.builder().rowMetadata(metadata).rowsUpdated(1).build();
600+
601+
recorder.addStubbing(s -> s.startsWith("INSERT"), result);
602+
603+
entityTemplate.insert(new WithMoney(null, new Money((byte) 1))).as(StepVerifier::create) //
604+
.expectNextCount(1) //
605+
.verifyComplete();
606+
607+
StatementRecorder.RecordedStatement statement = recorder.getCreatedStatement(s -> s.startsWith("INSERT"));
608+
609+
assertThat(statement.getSql()).isEqualTo("INSERT INTO with_money (money) VALUES ($1)");
610+
assertThat(statement.getBindings()).hasSize(1).containsEntry(0,
611+
Parameter.from(Parameters.in(R2dbcType.VARCHAR, "$$$")));
612+
}
613+
587614
record WithoutId(String name) {
588615
}
589616

590-
interface Named{
617+
interface Named {
591618
String getName();
592619
}
593620

@@ -784,4 +811,19 @@ public Mono<Person> onAfterConvert(Person entity, SqlIdentifier table) {
784811
return Mono.just(person);
785812
}
786813
}
814+
815+
record WithMoney(@Id Integer id, Money money) {
816+
}
817+
818+
record Money(byte amount) {
819+
}
820+
821+
static class MoneyConverter implements Converter<Money, io.r2dbc.spi.Parameter> {
822+
823+
@Override
824+
public io.r2dbc.spi.Parameter convert(Money source) {
825+
return Parameters.in(R2dbcType.VARCHAR, "$$$");
826+
}
827+
828+
}
787829
}

0 commit comments

Comments
 (0)