diff --git a/src/main/java/org/springframework/data/redis/core/convert/MappingRedisConverter.java b/src/main/java/org/springframework/data/redis/core/convert/MappingRedisConverter.java index 30378c9c2..e12683015 100644 --- a/src/main/java/org/springframework/data/redis/core/convert/MappingRedisConverter.java +++ b/src/main/java/org/springframework/data/redis/core/convert/MappingRedisConverter.java @@ -107,6 +107,7 @@ import org.springframework.util.comparator.NullSafeComparator; * @author Christoph Strobl * @author Greg Turnquist * @author Mark Paluch + * @author Golam Mazid Sajib * @since 1.7 */ public class MappingRedisConverter implements RedisConverter, InitializingBean { @@ -564,7 +565,10 @@ public class MappingRedisConverter implements RedisConverter, InitializingBean { if (customConversions.hasCustomWriteTarget(value.getClass())) { - if (!StringUtils.hasText(path) && customConversions.getCustomWriteTarget(value.getClass()).equals(byte[].class)) { + Optional> targetType = customConversions.getCustomWriteTarget(value.getClass()); + + if (!StringUtils.hasText(path) && targetType.isPresent() + && (targetType.get().equals(byte[].class) || ClassUtils.isAssignable(byte[].class, targetType.get()))) { sink.getBucket().put(StringUtils.hasText(path) ? path : "_raw", conversionService.convert(value, byte[].class)); } else { diff --git a/src/test/java/org/springframework/data/redis/core/convert/ConversionTestEntities.java b/src/test/java/org/springframework/data/redis/core/convert/ConversionTestEntities.java index 660891434..9fbf1b99f 100644 --- a/src/test/java/org/springframework/data/redis/core/convert/ConversionTestEntities.java +++ b/src/test/java/org/springframework/data/redis/core/convert/ConversionTestEntities.java @@ -18,6 +18,8 @@ package org.springframework.data.redis.core.convert; import lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; import java.time.Duration; import java.time.Instant; @@ -46,12 +48,14 @@ import org.springframework.data.redis.core.index.Indexed; /** * @author Christoph Strobl * @author Mark Paluch + * @author Golam Mazid Sajib */ public class ConversionTestEntities { static final String KEYSPACE_PERSON = "persons"; static final String KEYSPACE_TWOT = "twot"; static final String KEYSPACE_LOCATION = "locations"; + static final String KEYSPACE_ACCOUNT = "accounts"; @RedisHash(KEYSPACE_PERSON) public static class Person { @@ -240,4 +244,14 @@ public class ConversionTestEntities { List values; } + + @RedisHash(KEYSPACE_ACCOUNT) + @Getter + @Setter + public static class AccountInfo { + + @Id private String id; + private String account; + private String accountName; + } } diff --git a/src/test/java/org/springframework/data/redis/core/convert/MappingRedisConverterUnitTests.java b/src/test/java/org/springframework/data/redis/core/convert/MappingRedisConverterUnitTests.java index bff383fd5..3f111b30d 100644 --- a/src/test/java/org/springframework/data/redis/core/convert/MappingRedisConverterUnitTests.java +++ b/src/test/java/org/springframework/data/redis/core/convert/MappingRedisConverterUnitTests.java @@ -20,6 +20,7 @@ import static org.mockito.Mockito.*; import static org.springframework.data.redis.core.convert.ConversionTestEntities.*; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.time.Duration; import java.time.Instant; import java.time.LocalDate; @@ -45,7 +46,6 @@ import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; - import org.springframework.core.convert.converter.Converter; import org.springframework.data.convert.ReadingConverter; import org.springframework.data.convert.WritingConverter; @@ -67,6 +67,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; * @author Christoph Strobl * @author Greg Turnquist * @author Mark Paluch + * @author Golam Mazid Sajib */ @RunWith(MockitoJUnitRunner.class) public class MappingRedisConverterUnitTests { @@ -1946,4 +1947,67 @@ public class MappingRedisConverterUnitTests { } } + @Test // DATAREDIS-911 + public void writeEntityWithCustomConverter() { + + this.converter = new MappingRedisConverter(null, null, resolverMock); + this.converter + .setCustomConversions(new RedisCustomConversions(Collections.singletonList(new AccountInfoToBytesConverter()))); + this.converter.afterPropertiesSet(); + + AccountInfo accountInfo = new AccountInfo(); + accountInfo.setId("ai-id-1"); + accountInfo.setAccount("123456"); + accountInfo.setAccountName("Inamur Rahman Sadid"); + + assertThat(write(accountInfo).getRedisData().getId()).isEqualTo(accountInfo.getId()); + } + + @Test // DATAREDIS-911 + public void readEntityWithCustomConverter() { + + this.converter = new MappingRedisConverter(null, null, resolverMock); + this.converter + .setCustomConversions(new RedisCustomConversions(Collections.singletonList(new BytesToAccountInfoConverter()))); + this.converter.afterPropertiesSet(); + + Bucket bucket = new Bucket(); + bucket.put("_raw", "ai-id-1|123456|Golam Mazid Sajib".getBytes(StandardCharsets.UTF_8)); + + RedisData redisData = new RedisData(bucket); + redisData.setKeyspace(KEYSPACE_ACCOUNT); + redisData.setId("ai-id-1"); + + AccountInfo target = converter.read(AccountInfo.class, redisData); + + assertThat(target.getAccount()).isEqualTo("123456"); + assertThat(target.getAccountName()).isEqualTo("Golam Mazid Sajib"); + } + + @WritingConverter + static class AccountInfoToBytesConverter implements Converter { + + @Override + public byte[] convert(AccountInfo accountInfo) { + StringBuilder resp = new StringBuilder(); + resp.append(accountInfo.getId()).append("|").append(accountInfo.getAccount()).append("|") + .append(accountInfo.getAccountName()); + return resp.toString().getBytes(StandardCharsets.UTF_8); + } + } + + @ReadingConverter + static class BytesToAccountInfoConverter implements Converter { + + @Override + public AccountInfo convert(byte[] bytes) { + String[] values = new String(bytes, StandardCharsets.UTF_8).split("\\|"); + AccountInfo accountInfo = new AccountInfo(); + accountInfo.setId(values[0]); + accountInfo.setAccount(values[1]); + accountInfo.setAccountName(values[2]); + return accountInfo; + } + } + }