diff --git a/src/main/java/org/springframework/data/r2dbc/convert/MappingR2dbcConverter.java b/src/main/java/org/springframework/data/r2dbc/convert/MappingR2dbcConverter.java index 6b1afec..77a408d 100644 --- a/src/main/java/org/springframework/data/r2dbc/convert/MappingR2dbcConverter.java +++ b/src/main/java/org/springframework/data/r2dbc/convert/MappingR2dbcConverter.java @@ -190,7 +190,6 @@ public class MappingR2dbcConverter extends BasicRelationalConverter implements R } } - public Object readValue(@Nullable Object value, TypeInformation type) { if (null == value) { @@ -553,6 +552,8 @@ public class MappingR2dbcConverter extends BasicRelationalConverter implements R actualType = property.getActualType(); } + actualType = getTargetType(actualType); + Class targetType = arrayColumns.getArrayType(actualType); if (!property.isArray() || !targetType.isAssignableFrom(value.getClass())) { diff --git a/src/main/java/org/springframework/data/r2dbc/core/DefaultReactiveDataAccessStrategy.java b/src/main/java/org/springframework/data/r2dbc/core/DefaultReactiveDataAccessStrategy.java index 83d394e..954cdfa 100644 --- a/src/main/java/org/springframework/data/r2dbc/core/DefaultReactiveDataAccessStrategy.java +++ b/src/main/java/org/springframework/data/r2dbc/core/DefaultReactiveDataAccessStrategy.java @@ -240,7 +240,6 @@ public class DefaultReactiveDataAccessStrategy implements ReactiveDataAccessStra ArrayColumns arrayColumns = this.dialect.getArraySupport(); if (!arrayColumns.isSupported()) { - throw new InvalidDataAccessResourceUsageException( "Dialect " + this.dialect.getClass().getName() + " does not support array columns"); } @@ -266,8 +265,7 @@ public class DefaultReactiveDataAccessStrategy implements ReactiveDataAccessStra return Parameter.empty(targetArrayType); } - return Parameter.fromOrEmpty(this.converter.getArrayValue(arrayColumns, property, value.getValue()), - actualType); + return Parameter.fromOrEmpty(this.converter.getArrayValue(arrayColumns, property, value.getValue()), actualType); } /* diff --git a/src/test/java/org/springframework/data/r2dbc/core/PostgresReactiveDataAccessStrategyTests.java b/src/test/java/org/springframework/data/r2dbc/core/PostgresReactiveDataAccessStrategyTests.java index f940502..d6d49a1 100644 --- a/src/test/java/org/springframework/data/r2dbc/core/PostgresReactiveDataAccessStrategyTests.java +++ b/src/test/java/org/springframework/data/r2dbc/core/PostgresReactiveDataAccessStrategyTests.java @@ -17,8 +17,11 @@ package org.springframework.data.r2dbc.core; import static org.springframework.data.r2dbc.testing.Assertions.*; +import io.r2dbc.postgresql.codec.Interval; import lombok.RequiredArgsConstructor; +import java.time.Duration; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.EnumSet; @@ -28,6 +31,7 @@ import java.util.Set; import org.junit.jupiter.api.Test; import org.springframework.core.convert.converter.Converter; +import org.springframework.data.convert.ReadingConverter; import org.springframework.data.convert.WritingConverter; import org.springframework.data.r2dbc.convert.EnumWriteSupport; import org.springframework.data.r2dbc.dialect.PostgresDialect; @@ -41,7 +45,8 @@ import org.springframework.data.relational.core.sql.SqlIdentifier; */ public class PostgresReactiveDataAccessStrategyTests extends ReactiveDataAccessStrategyTestSupport { - private final ReactiveDataAccessStrategy strategy = new DefaultReactiveDataAccessStrategy(PostgresDialect.INSTANCE); + private final ReactiveDataAccessStrategy strategy = new DefaultReactiveDataAccessStrategy(PostgresDialect.INSTANCE, + Arrays.asList(DurationToIntervalConverter.INSTANCE, IntervalToDurationConverter.INSTANCE)); @Override protected ReactiveDataAccessStrategy getStrategy() { @@ -116,6 +121,17 @@ public class PostgresReactiveDataAccessStrategyTests extends ReactiveDataAccessS assertThat(outboundRow).containsColumn("my_objects").withColumn("my_objects").isEmpty().hasType(String.class); } + @Test // gh-796 + void shouldApplyCustomConversionForEmptyList() { + + WithDuration withDuration = new WithDuration(); + withDuration.durations = new ArrayList<>(); + + OutboundRow outboundRow = strategy.getOutboundRow(withDuration); + + assertThat(outboundRow).containsColumn("durations").withColumn("durations").hasType(Interval[].class); + } + @Test // gh-252, gh-593 void shouldConvertCollectionOfEnumToString() { @@ -202,6 +218,11 @@ public class PostgresReactiveDataAccessStrategyTests extends ReactiveDataAccessS List stringList; } + static class WithDuration { + + List durations; + } + static class WithEnumCollections { MyEnum[] enumArray; @@ -242,5 +263,27 @@ public class PostgresReactiveDataAccessStrategyTests extends ReactiveDataAccessS } } + @WritingConverter + enum DurationToIntervalConverter implements Converter { + + INSTANCE; + + @Override + public Interval convert(Duration duration) { + return Interval.of(duration); + } + } + + @ReadingConverter + enum IntervalToDurationConverter implements Converter { + + INSTANCE; + + @Override + public Duration convert(Interval interval) { + return interval.getDuration(); + } + } + private static class MyEnumSupport extends EnumWriteSupport {} }