From 6f2bb59ceb2ee2265456cf72baf250ce6b3029db Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Tue, 5 May 2020 13:27:04 +0200 Subject: [PATCH] DATAJDBC-412 - Support custom single value types in id. Custom value types like outlined below can now server as id property public class IdValue { String id; } public class DomainType { @Id IdValue id; String value; // ... } --- .../jdbc/core/convert/BasicJdbcConverter.java | 6 +- .../DefaultDataAccessStrategyUnitTests.java | 61 +++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/BasicJdbcConverter.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/BasicJdbcConverter.java index e4d06f0dd..0c5921179 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/BasicJdbcConverter.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/core/convert/BasicJdbcConverter.java @@ -311,7 +311,11 @@ public class BasicJdbcConverter extends BasicRelationalConverter implements Jdbc private JdbcValue tryToConvertToJdbcValue(@Nullable Object value) { if (canWriteAsJdbcValue(value)) { - return (JdbcValue) writeValue(value, ClassTypeInformation.from(JdbcValue.class)); + Object converted = writeValue(value, ClassTypeInformation.from(JdbcValue.class)); + if(converted instanceof JdbcValue) { + return (JdbcValue) converted; + } + } return null; diff --git a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategyUnitTests.java b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategyUnitTests.java index feaafa24c..42cdf1282 100644 --- a/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategyUnitTests.java +++ b/spring-data-jdbc/src/test/java/org/springframework/data/jdbc/core/convert/DefaultDataAccessStrategyUnitTests.java @@ -21,11 +21,13 @@ import static org.mockito.Mockito.*; import static org.springframework.data.relational.core.sql.SqlIdentifier.*; import lombok.AllArgsConstructor; +import lombok.Data; import lombok.RequiredArgsConstructor; import java.util.Arrays; import java.util.HashMap; +import lombok.Value; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; @@ -142,6 +144,43 @@ public class DefaultDataAccessStrategyUnitTests { assertThat(paramSourceCaptor.getValue().getValue("flag")).isEqualTo("T"); } + @Test // DATAJDBC-412 + public void considersConfiguredWriteConverterForIdValueObjects() { + + DelegatingDataAccessStrategy relationResolver = new DelegatingDataAccessStrategy(); + + Dialect dialect = HsqlDbDialect.INSTANCE; + + JdbcConverter converter = new BasicJdbcConverter(context, relationResolver, + new JdbcCustomConversions(Arrays.asList(IdValueToStringConverter.INSTANCE)), + new DefaultJdbcTypeFactory(jdbcOperations), dialect.getIdentifierProcessing()); + + DefaultDataAccessStrategy accessStrategy = new DefaultDataAccessStrategy( // + new SqlGeneratorSource(context, converter, dialect), // + context, // + converter, // + namedJdbcOperations); + + relationResolver.setDelegate(accessStrategy); + + String rawId = "batman"; + + WithValueObjectId entity = new WithValueObjectId(new IdValue(rawId)); + entity.value = "vs. superman"; + + accessStrategy.insert(entity, WithValueObjectId.class, Identifier.empty()); + + verify(namedJdbcOperations).update(anyString(), paramSourceCaptor.capture(), any(KeyHolder.class)); + + assertThat(paramSourceCaptor.getValue().getValue("id")).isEqualTo(rawId); + assertThat(paramSourceCaptor.getValue().getValue("value")).isEqualTo("vs. superman"); + + accessStrategy.findById(new IdValue(rawId), WithValueObjectId.class); + + verify(namedJdbcOperations).queryForObject(anyString(), paramSourceCaptor.capture(), any(EntityRowMapper.class)); + assertThat(paramSourceCaptor.getValue().getValue("id")).isEqualTo(rawId); + } + @RequiredArgsConstructor private static class DummyEntity { @@ -155,6 +194,18 @@ public class DefaultDataAccessStrategyUnitTests { boolean flag; } + @Data + private static class WithValueObjectId { + + @Id private final IdValue id; + String value; + } + + @Value + private static class IdValue { + String id; + } + @WritingConverter enum BooleanToStringConverter implements Converter { @@ -177,4 +228,14 @@ public class DefaultDataAccessStrategyUnitTests { } } + @WritingConverter + enum IdValueToStringConverter implements Converter { + + INSTANCE; + + @Override + public String convert(IdValue source) { + return source.id; + } + } }