diff --git a/src/test/java/org/springframework/data/redis/cache/RedisCacheTests.java b/src/test/java/org/springframework/data/redis/cache/RedisCacheTests.java index abc4c1c20..d531eef94 100644 --- a/src/test/java/org/springframework/data/redis/cache/RedisCacheTests.java +++ b/src/test/java/org/springframework/data/redis/cache/RedisCacheTests.java @@ -15,14 +15,10 @@ */ package org.springframework.data.redis.cache; -import static org.assertj.core.api.Assertions.*; -import static org.assertj.core.api.Assumptions.*; - -import io.netty.util.concurrent.DefaultThreadFactory; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.RequiredArgsConstructor; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; +import static org.assertj.core.api.Assumptions.assumeThat; import java.io.Serializable; import java.nio.charset.StandardCharsets; @@ -30,6 +26,7 @@ import java.time.Duration; import java.util.Collection; import java.util.Collections; import java.util.Date; +import java.util.Objects; import java.util.concurrent.CountDownLatch; import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.ThreadPoolExecutor; @@ -54,6 +51,8 @@ import org.springframework.data.redis.test.extension.parametrized.MethodSource; import org.springframework.data.redis.test.extension.parametrized.ParameterizedRedisTest; import org.springframework.lang.Nullable; +import io.netty.util.concurrent.DefaultThreadFactory; + /** * Tests for {@link RedisCache} with {@link DefaultRedisCacheWriter} using different {@link RedisSerializer} and * {@link RedisConnectionFactory} pairs. @@ -62,6 +61,7 @@ import org.springframework.lang.Nullable; * @author Mark Paluch * @author Piotr Mionskowski * @author Jos Roseboom + * @author John Blum */ @MethodSource("testParams") public class RedisCacheTests { @@ -225,7 +225,7 @@ public class RedisCacheTests { @ParameterizedRedisTest // DATAREDIS-481 void shouldRejectNonInvalidKey() { - InvalidKey key = new InvalidKey(sample.getFirstame(), sample.getBirthdate()); + InvalidKey key = new InvalidKey(sample.getFirstname(), sample.getBirthdate()); assertThatIllegalStateException().isThrownBy(() -> cache.put(key, sample)); } @@ -233,7 +233,7 @@ public class RedisCacheTests { @ParameterizedRedisTest // DATAREDIS-481 void shouldAllowComplexKeyWithToStringMethod() { - ComplexKey key = new ComplexKey(sample.getFirstame(), sample.getBirthdate()); + ComplexKey key = new ComplexKey(sample.getFirstname(), sample.getBirthdate()); cache.put(key, sample); @@ -418,11 +418,11 @@ public class RedisCacheTests { void cacheShouldAllowListCacheKeysOfComplexTypes() { Object key = SimpleKeyGenerator - .generateKey(Collections.singletonList(new ComplexKey(sample.getFirstame(), sample.getBirthdate()))); + .generateKey(Collections.singletonList(new ComplexKey(sample.getFirstname(), sample.getBirthdate()))); cache.put(key, sample); ValueWrapper target = cache.get(SimpleKeyGenerator - .generateKey(Collections.singletonList(new ComplexKey(sample.getFirstame(), sample.getBirthdate())))); + .generateKey(Collections.singletonList(new ComplexKey(sample.getFirstname(), sample.getBirthdate())))); assertThat(target.get()).isEqualTo(sample); } @@ -430,11 +430,11 @@ public class RedisCacheTests { void cacheShouldAllowMapCacheKeys() { Object key = SimpleKeyGenerator - .generateKey(Collections.singletonMap("map-key", new ComplexKey(sample.getFirstame(), sample.getBirthdate()))); + .generateKey(Collections.singletonMap("map-key", new ComplexKey(sample.getFirstname(), sample.getBirthdate()))); cache.put(key, sample); ValueWrapper target = cache.get(SimpleKeyGenerator - .generateKey(Collections.singletonMap("map-key", new ComplexKey(sample.getFirstame(), sample.getBirthdate())))); + .generateKey(Collections.singletonMap("map-key", new ComplexKey(sample.getFirstname(), sample.getBirthdate())))); assertThat(target.get()).isEqualTo(sample); } @@ -442,7 +442,7 @@ public class RedisCacheTests { void cacheShouldFailOnNonConvertibleCacheKey() { Object key = SimpleKeyGenerator - .generateKey(Collections.singletonList(new InvalidKey(sample.getFirstame(), sample.getBirthdate()))); + .generateKey(Collections.singletonList(new InvalidKey(sample.getFirstname(), sample.getBirthdate()))); assertThatExceptionOfType(IllegalStateException.class).isThrownBy(() -> cache.put(key, sample)); } @@ -537,24 +537,115 @@ public class RedisCacheTests { } } - @Data - @NoArgsConstructor - @AllArgsConstructor static class Person implements Serializable { - String firstame; - Date birthdate; + + private String firstname; + private Date birthdate; + + public Person() { } + + public Person(String firstname, Date birthdate) { + this.firstname = firstname; + this.birthdate = birthdate; + } + + public String getFirstname() { + return this.firstname; + } + + public void setFirstname(String firstname) { + this.firstname = firstname; + } + + public Date getBirthdate() { + return this.birthdate; + } + + public void setBirthdate(Date birthdate) { + this.birthdate = birthdate; + } + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof Person that)) { + return false; + } + + return Objects.equals(this.getFirstname(), that.getFirstname()) + && Objects.equals(this.getBirthdate(), that.getBirthdate()); + } + + @Override + public int hashCode() { + return Objects.hash(getFirstname(), getBirthdate()); + } + + @Override + public String toString() { + return "RedisCacheTests.Person(firstname=" + this.getFirstname() + + ", birthdate=" + this.getBirthdate() + ")"; + } } - @RequiredArgsConstructor // toString not overridden + // toString not overridden static class InvalidKey implements Serializable { - final String firstame; + + final String firstname; final Date birthdate; + + public InvalidKey(String firstname, Date birthdate) { + this.firstname = firstname; + this.birthdate = birthdate; + } } - @Data - @RequiredArgsConstructor static class ComplexKey implements Serializable { - final String firstame; + + final String firstname; final Date birthdate; + + public ComplexKey(String firstname, Date birthdate) { + this.firstname = firstname; + this.birthdate = birthdate; + } + + public String getFirstname() { + return this.firstname; + } + + public Date getBirthdate() { + return this.birthdate; + } + + @Override + public boolean equals(final Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof ComplexKey that)) { + return false; + } + + return Objects.equals(this.getFirstname(), that.getFirstname()) + && Objects.equals(this.getBirthdate(), that.getBirthdate()); + } + + @Override + public int hashCode() { + return Objects.hash(getFirstname(), getBirthdate()); + } + + @Override + public String toString() { + return "RedisCacheTests.ComplexKey(firstame=" + this.getFirstname() + + ", birthdate=" + this.getBirthdate() + ")"; + } } } diff --git a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionFactoryUnitTests.java b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionFactoryUnitTests.java index 2c8356b34..1c68c5d3a 100644 --- a/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionFactoryUnitTests.java +++ b/src/test/java/org/springframework/data/redis/connection/lettuce/LettuceConnectionFactoryUnitTests.java @@ -15,32 +15,24 @@ */ package org.springframework.data.redis.connection.lettuce; -import static org.assertj.core.api.Assertions.*; -import static org.mockito.Mockito.*; -import static org.springframework.data.redis.connection.ClusterTestVariables.*; -import static org.springframework.data.redis.connection.RedisConfiguration.*; -import static org.springframework.data.redis.test.extension.LettuceTestClientResources.*; -import static org.springframework.test.util.ReflectionTestUtils.*; - -import io.lettuce.core.AbstractRedisClient; -import io.lettuce.core.ClientOptions; -import io.lettuce.core.RedisClient; -import io.lettuce.core.RedisURI; -import io.lettuce.core.api.StatefulConnection; -import io.lettuce.core.api.StatefulRedisConnection; -import io.lettuce.core.cluster.ClusterClientOptions; -import io.lettuce.core.cluster.RedisClusterClient; -import io.lettuce.core.cluster.api.StatefulRedisClusterConnection; -import io.lettuce.core.cluster.api.sync.RedisAdvancedClusterCommands; -import io.lettuce.core.codec.ByteArrayCodec; -import io.lettuce.core.codec.RedisCodec; -import io.lettuce.core.resource.ClientResources; -import lombok.AllArgsConstructor; -import lombok.Data; -import reactor.test.StepVerifier; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.withSettings; +import static org.springframework.data.redis.connection.ClusterTestVariables.CLUSTER_NODE_1; +import static org.springframework.data.redis.connection.RedisConfiguration.WithHostAndPort; +import static org.springframework.data.redis.test.extension.LettuceTestClientResources.getSharedClientResources; +import static org.springframework.test.util.ReflectionTestUtils.getField; import java.time.Duration; import java.util.Collections; +import java.util.Objects; import java.util.concurrent.CompletableFuture; import org.junit.jupiter.api.AfterEach; @@ -48,6 +40,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.mockito.ArgumentMatchers; + import org.springframework.beans.DirectFieldAccessor; import org.springframework.beans.factory.DisposableBean; import org.springframework.data.redis.ConnectionFactoryTracker; @@ -65,6 +58,22 @@ import org.springframework.data.redis.connection.RedisStandaloneConfiguration; import org.springframework.data.redis.test.extension.LettuceTestClientResources; import org.springframework.test.util.ReflectionTestUtils; +import io.lettuce.core.AbstractRedisClient; +import io.lettuce.core.ClientOptions; +import io.lettuce.core.RedisClient; +import io.lettuce.core.RedisURI; +import io.lettuce.core.api.StatefulConnection; +import io.lettuce.core.api.StatefulRedisConnection; +import io.lettuce.core.cluster.ClusterClientOptions; +import io.lettuce.core.cluster.RedisClusterClient; +import io.lettuce.core.cluster.api.StatefulRedisClusterConnection; +import io.lettuce.core.cluster.api.sync.RedisAdvancedClusterCommands; +import io.lettuce.core.codec.ByteArrayCodec; +import io.lettuce.core.codec.RedisCodec; +import io.lettuce.core.resource.ClientResources; + +import reactor.test.StepVerifier; + /** * Unit tests for {@link LettuceConnectionFactory}. * @@ -75,6 +84,7 @@ import org.springframework.test.util.ReflectionTestUtils; * @author Luis De Bello * @author Andrea Como * @author Chris Bono + * @author John Blum */ class LettuceConnectionFactoryUnitTests { @@ -1216,8 +1226,6 @@ class LettuceConnectionFactoryUnitTests { assertThat(configuration).isEqualTo(expected); } - @Data - @AllArgsConstructor static class CustomRedisConfiguration implements RedisConfiguration, WithHostAndPort { private String hostName; @@ -1226,5 +1234,59 @@ class LettuceConnectionFactoryUnitTests { CustomRedisConfiguration(String hostName) { this(hostName, 6379); } + + CustomRedisConfiguration(String hostName, int port) { + this.hostName = hostName; + this.port = port; + } + + @Override + public String getHostName() { + return this.hostName; + } + + @Override + public void setHostName(String hostName) { + this.hostName = hostName; + } + + @Override + public int getPort() { + return this.port; + } + + @Override + public void setPort(int port) { + this.port = port; + } + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof CustomRedisConfiguration that)) { + return false; + } + + return Objects.equals(this.getHostName(), that.getHostName()) + && Objects.equals(this.getPort(), that.getPort()); + } + + @Override + public int hashCode() { + return Objects.hash(getHostName(), getPort()); + } + + @Override + public String toString() { + + return "CustomRedisConfiguration{" + + "hostName='" + hostName + '\'' + + ", port=" + port + + '}'; + } } } diff --git a/src/test/java/org/springframework/data/redis/core/RedisKeyValueTemplateTests.java b/src/test/java/org/springframework/data/redis/core/RedisKeyValueTemplateTests.java index 664d4c9ba..e26afc644 100644 --- a/src/test/java/org/springframework/data/redis/core/RedisKeyValueTemplateTests.java +++ b/src/test/java/org/springframework/data/redis/core/RedisKeyValueTemplateTests.java @@ -15,12 +15,7 @@ */ package org.springframework.data.redis.core; -import static org.assertj.core.api.Assertions.*; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.With; +import static org.assertj.core.api.Assertions.assertThat; import java.util.ArrayList; import java.util.Arrays; @@ -28,6 +23,7 @@ import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import org.junit.jupiter.api.AfterEach; @@ -45,13 +41,13 @@ import org.springframework.data.redis.test.extension.RedisStanalone; import org.springframework.data.redis.test.extension.parametrized.MethodSource; import org.springframework.data.redis.test.extension.parametrized.ParameterizedRedisTest; import org.springframework.lang.Nullable; -import org.springframework.util.ObjectUtils; /** * Integration tests for {@link RedisKeyValueTemplate}. * * @author Christoph Strobl * @author Mark Paluch + * @author John Blum */ @MethodSource("params") public class RedisKeyValueTemplateTests { @@ -810,7 +806,6 @@ public class RedisKeyValueTemplateTests { assertThat(immutableObject.value).isEqualTo(inserted.value); } - @EqualsAndHashCode @RedisHash("template-test-type-mapping") static class VariousTypes { @@ -828,6 +823,38 @@ public class RedisKeyValueTemplateTests { Map simpleTypedMap; Map complexTypedMap; Map untypedMap; + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof VariousTypes that)) { + return false; + } + + return Objects.equals(this.id, that.id) + && Objects.equals(this.stringValue, that.stringValue) + && Objects.equals(this.integerValue, that.integerValue) + && Objects.equals(this.complexValue, that.complexValue) + && Objects.equals(this.objectValue, that.objectValue) + && Objects.equals(this.simpleTypedList, that.simpleTypedList) + && Objects.equals(this.complexTypedList, that.complexTypedList) + && Objects.equals(this.untypedList, that.untypedList) + && Objects.equals(this.simpleTypedMap, that.simpleTypedMap) + && Objects.equals(this.complexTypedMap, that.complexTypedMap) + && Objects.equals(this.untypedMap, that.untypedMap); + } + + @Override + public int hashCode() { + + return Objects.hash(this.id, this.stringValue, this.integerValue, this.complexValue, this.objectValue, + this.simpleTypedList, this.complexTypedList, this.untypedList, this.simpleTypedMap, + this.complexTypedMap, this.untypedMap); + } } static class Item { @@ -870,45 +897,27 @@ public class RedisKeyValueTemplateTests { this.age = age; } - @Override - public int hashCode() { - - int result = ObjectUtils.nullSafeHashCode(firstname); - result += ObjectUtils.nullSafeHashCode(lastname); - result += ObjectUtils.nullSafeHashCode(age); - result += ObjectUtils.nullSafeHashCode(nicknames); - return result + ObjectUtils.nullSafeHashCode(id); - } - @Override public boolean equals(@Nullable Object obj) { + if (this == obj) { return true; } - if (obj == null) { - return false; - } - if (!(obj instanceof Person)) { - return false; - } - Person that = (Person) obj; - if (!ObjectUtils.nullSafeEquals(this.firstname, that.firstname)) { + if (!(obj instanceof Person that)) { return false; } - if (!ObjectUtils.nullSafeEquals(this.lastname, that.lastname)) { - return false; - } + return Objects.equals(this.id, that.id) + && Objects.equals(this.firstname, that.firstname) + && Objects.equals(this.lastname, that.lastname) + && Objects.equals(this.age, that.age) + && Objects.equals(this.nicknames, that.nicknames); + } - if (!ObjectUtils.nullSafeEquals(this.age, that.age)) { - return false; - } - if (!ObjectUtils.nullSafeEquals(this.nicknames, that.nicknames)) { - return false; - } - - return ObjectUtils.nullSafeEquals(this.id, that.id); + @Override + public int hashCode() { + return Objects.hash(this.firstname, this.lastname, this.age, this.nicknames, this.id); } @Override @@ -919,25 +928,110 @@ public class RedisKeyValueTemplateTests { } - @Data static class WithTtl { @Id String id; String value; @TimeToLive Long ttl; + + public String getId() { + return this.id; + } + + public void setId(String id) { + this.id = id; + } + + public String getValue() { + return this.value; + } + + public void setValue(String value) { + this.value = value; + } + + public Long getTtl() { + return this.ttl; + } + + public void setTtl(Long ttl) { + this.ttl = ttl; + } + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof WithTtl that)) { + return false; + } + + return Objects.equals(this.getId(), that.getId()) + && Objects.equals(this.getTtl(), that.getTtl()) + && Objects.equals(this.getValue(), that.getValue()); + } + + @Override + public int hashCode() { + return Objects.hash(getId(), getTtl(), getValue()); + } } - @Data static class WithPrimitiveTtl { @Id String id; String value; @TimeToLive int ttl; + + public String getId() { + return this.id; + } + + public void setId(String id) { + this.id = id; + } + + public String getValue() { + return this.value; + } + + public void setValue(String value) { + this.value = value; + } + + public int getTtl() { + return this.ttl; + } + + public void setTtl(int ttl) { + this.ttl = ttl; + } + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof WithPrimitiveTtl that)) { + return false; + } + + return Objects.equals(this.getId(), that.getId()) + && Objects.equals(this.getTtl(), that.getTtl()) + && Objects.equals(this.getValue(), that.getValue()); + } + + @Override + public int hashCode() { + return Objects.hash(getId(), getTtl(), getValue()); + } } - @Data - @With - @AllArgsConstructor static class ImmutableObject { final @Id String id; @@ -949,5 +1043,64 @@ public class RedisKeyValueTemplateTests { this.value = null; this.ttl = null; } + + public ImmutableObject(String id, String value, Long ttl) { + this.id = id; + this.value = value; + this.ttl = ttl; + } + + public String getId() { + return this.id; + } + + public String getValue() { + return this.value; + } + + public Long getTtl() { + return this.ttl; + } + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof ImmutableObject that)) { + return false; + } + + return Objects.equals(this.getId(), that.getId()) + && Objects.equals(this.getTtl(), that.getTtl()) + && Objects.equals(this.getValue(), that.getValue()); + } + + @Override + public int hashCode() { + return Objects.hash(getId(), getTtl(), getValue()); + } + + @Override + public String toString() { + + return "RedisKeyValueTemplateTests.ImmutableObject(id=" + this.getId() + + ", value=" + this.getValue() + + ", ttl=" + this.getTtl() + ")"; + } + + public ImmutableObject withId(String id) { + return Objects.equals(getId(), id) ? this : new ImmutableObject(id, this.value, this.ttl); + } + + public ImmutableObject withTtl(Long ttl) { + return Objects.equals(getTtl(), ttl) ? this : new ImmutableObject(this.id, this.value, ttl); + } + + public ImmutableObject withValue(String value) { + return Objects.equals(getValue(), value) ? this : new ImmutableObject(this.id, value, this.ttl); + } } } 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 3d4829033..42c7eac7a 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 @@ -15,10 +15,6 @@ */ package org.springframework.data.redis.core.convert; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; - import java.time.Duration; import java.time.Instant; import java.time.LocalDate; @@ -32,6 +28,7 @@ import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.UUID; import java.util.concurrent.TimeUnit; @@ -47,6 +44,7 @@ import org.springframework.data.redis.core.index.Indexed; * @author Christoph Strobl * @author Mark Paluch * @author Golam Mazid Sajib + * @author John Blum */ public class ConversionTestEntities { @@ -91,25 +89,121 @@ public class ConversionTestEntities { } @RedisHash(KEYSPACE_PERSON) - @Data public static class RecursiveConstructorPerson { final @Id String id; + final String firstname; - final RecursiveConstructorPerson father; + String lastname; + + final RecursiveConstructorPerson father; + + public RecursiveConstructorPerson(String id, String firstname, RecursiveConstructorPerson father) { + this.id = id; + this.firstname = firstname; + this.father = father; + } + + public String getId() { + return this.id; + } + + public String getFirstname() { + return this.firstname; + } + + public RecursiveConstructorPerson getFather() { + return this.father; + } + + public String getLastname() { + return this.lastname; + } + + public void setLastname(String lastname) { + this.lastname = lastname; + } + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof RecursiveConstructorPerson that)) { + return false; + } + + return Objects.equals(this.getId(), that.getId()) + && Objects.equals(this.getFirstname(), that.getFirstname()) + && Objects.equals(this.getLastname(), that.getLastname()) + && Objects.equals(this.getFather(), that.getFather()); + } + + @Override + public int hashCode() { + return Objects.hash(getId(), getFirstname(), getLastname(), getFather()); + } + + @Override + public String toString() { + + return "ConversionTestEntities.RecursiveConstructorPerson(id=" + this.getId() + + ", firstname=" + this.getFirstname() + + ", father=" + this.getFather() + + ", lastname=" + this.getLastname() + ")"; + } } @RedisHash(KEYSPACE_PERSON) - @Data public static class PersonWithConstructorAndAddress { final @Id String id; final Address address; + + public PersonWithConstructorAndAddress(String id, Address address) { + this.id = id; + this.address = address; + } + + public String getId() { + return this.id; + } + + public Address getAddress() { + return this.address; + } + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof PersonWithConstructorAndAddress that)) { + return false; + } + + return Objects.equals(this.getId(), that.getId()) + && Objects.equals(this.getAddress(), that.getAddress()); + } + + @Override + public int hashCode() { + return Objects.hash(getId(), getAddress()); + } + + @Override + public String toString() { + return "ConversionTestEntities.PersonWithConstructorAndAddress(id=" + this.getId() + + ", address=" + this.getAddress() + ")"; + } } public static class PersonWithAddressReference extends Person { - @Reference AddressWithId addressRef; } @@ -120,11 +214,11 @@ public class ConversionTestEntities { } public static class AddressWithId extends Address { - @Id String id; } - public static enum Gender { + public enum Gender { + MALE, FEMALE { @Override @@ -136,7 +230,6 @@ public class ConversionTestEntities { @TypeAlias("with-post-code") public static class AddressWithPostcode extends Address { - String postcode; } @@ -147,7 +240,6 @@ public class ConversionTestEntities { List items; } - @EqualsAndHashCode @RedisHash(KEYSPACE_LOCATION) public static class Location { @@ -155,6 +247,26 @@ public class ConversionTestEntities { String name; Address address; + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof Location that)) { + return false; + } + + return Objects.equals(this.id, that.id) + && Objects.equals(this.name, that.name) + && Objects.equals(this.address, that.address); + } + + @Override + public int hashCode() { + return Objects.hash(this.id, this.name, this.address); + } } @RedisHash(timeToLive = 5) @@ -220,36 +332,112 @@ public class ConversionTestEntities { Map dateMapKeyMapping; } - @AllArgsConstructor static class Device { final Instant now; final Set profiles; + + public Device(Instant now, Set profiles) { + this.now = now; + this.profiles = profiles; + } } - @Data public static class JustSomeDifferentPropertyTypes { UUID uuid; + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof JustSomeDifferentPropertyTypes that)) { + return false; + } + + return Objects.equals(this.uuid, that.uuid); + } + + @Override + public int hashCode() { + return Objects.hash(this.uuid); + } + + @Override + public String toString() { + return "ConversionTestEntities.JustSomeDifferentPropertyTypes(uuid=" + this.uuid + ")"; + } } static class Outer { - List inners; List values; } static class Inner { - List values; } @RedisHash(KEYSPACE_ACCOUNT) - @Data public static class AccountInfo { @Id private String id; private String account; private String accountName; + + public String getId() { + return this.id; + } + + public void setId(String id) { + this.id = id; + } + + public String getAccount() { + return this.account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAccountName() { + return this.accountName; + } + + public void setAccountName(String accountName) { + this.accountName = accountName; + } + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof AccountInfo that)) { + return false; + } + + return Objects.equals(this.getId(), that.getId()) + && Objects.equals(this.getAccount(), that.getAccount()) + && Objects.equals(this.getAccountName(), that.getAccountName()); + } + + @Override + public int hashCode() { + return Objects.hash(getId(), getAccount(), getAccountName()); + } + + @Override + public String toString() { + return "ConversionTestEntities.AccountInfo(id=" + this.getId() + + ", account=" + this.getAccount() + + ", accountName=" + this.getAccountName() + ")"; + } } } 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 6bc2a5671..8583dd525 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 @@ -15,11 +15,33 @@ */ package org.springframework.data.redis.core.convert; -import static org.assertj.core.api.Assertions.*; -import static org.mockito.Mockito.*; -import static org.springframework.data.redis.core.convert.ConversionTestEntities.*; - -import lombok.AllArgsConstructor; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.when; +import static org.springframework.data.redis.core.convert.ConversionTestEntities.AccountInfo; +import static org.springframework.data.redis.core.convert.ConversionTestEntities.Address; +import static org.springframework.data.redis.core.convert.ConversionTestEntities.AddressWithId; +import static org.springframework.data.redis.core.convert.ConversionTestEntities.AddressWithPostcode; +import static org.springframework.data.redis.core.convert.ConversionTestEntities.Device; +import static org.springframework.data.redis.core.convert.ConversionTestEntities.ExipringPersonWithExplicitProperty; +import static org.springframework.data.redis.core.convert.ConversionTestEntities.ExpiringPerson; +import static org.springframework.data.redis.core.convert.ConversionTestEntities.Gender; +import static org.springframework.data.redis.core.convert.ConversionTestEntities.JustSomeDifferentPropertyTypes; +import static org.springframework.data.redis.core.convert.ConversionTestEntities.KEYSPACE_ACCOUNT; +import static org.springframework.data.redis.core.convert.ConversionTestEntities.KEYSPACE_PERSON; +import static org.springframework.data.redis.core.convert.ConversionTestEntities.Location; +import static org.springframework.data.redis.core.convert.ConversionTestEntities.Outer; +import static org.springframework.data.redis.core.convert.ConversionTestEntities.Person; +import static org.springframework.data.redis.core.convert.ConversionTestEntities.PersonWithConstructorAndAddress; +import static org.springframework.data.redis.core.convert.ConversionTestEntities.RecursiveConstructorPerson; +import static org.springframework.data.redis.core.convert.ConversionTestEntities.Size; +import static org.springframework.data.redis.core.convert.ConversionTestEntities.Species; +import static org.springframework.data.redis.core.convert.ConversionTestEntities.TaVeren; +import static org.springframework.data.redis.core.convert.ConversionTestEntities.TheWheelOfTime; +import static org.springframework.data.redis.core.convert.ConversionTestEntities.TypeWithMaps; +import static org.springframework.data.redis.core.convert.ConversionTestEntities.TypeWithObjectValueTypes; +import static org.springframework.data.redis.core.convert.ConversionTestEntities.WithArrays; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; @@ -71,6 +93,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; * @author Greg Turnquist * @author Mark Paluch * @author Golam Mazid Sajib + * @author John Blum */ @ExtendWith(MockitoExtension.class) class MappingRedisConverterUnitTests { @@ -157,7 +180,8 @@ class MappingRedisConverterUnitTests { RedisTestData target = write(rand); - assertThat(target).containsEntry("nicknames.[0]", "dragon reborn").containsEntry("nicknames.[1]", "lews therin"); + assertThat(target).containsEntry("nicknames.[0]", "dragon reborn") + .containsEntry("nicknames.[1]", "lews therin"); } @Test // DATAREDIS-425 @@ -192,9 +216,9 @@ class MappingRedisConverterUnitTests { RedisTestData target = write(rand); assertThat(target).containsEntry("coworkers.[0].firstname", "mat") // - .containsEntry("coworkers.[0].nicknames.[0]", "prince of the ravens") // - .containsEntry("coworkers.[1].firstname", "perrin") // - .containsEntry("coworkers.[1].address.city", "two rivers"); + .containsEntry("coworkers.[0].nicknames.[0]", "prince of the ravens") // + .containsEntry("coworkers.[1].firstname", "perrin") // + .containsEntry("coworkers.[1].address.city", "two rivers"); } @Test // DATAREDIS-425 @@ -249,7 +273,7 @@ class MappingRedisConverterUnitTests { map.put("father.lastname", "Simpson"); RecursiveConstructorPerson target = converter.read(RecursiveConstructorPerson.class, - new RedisData(Bucket.newBucketFromStringMap(map))); + new RedisData(Bucket.newBucketFromStringMap(map))); assertThat(target.id).isEqualTo("bart"); assertThat(target.firstname).isEqualTo("Bart"); @@ -303,7 +327,7 @@ class MappingRedisConverterUnitTests { RedisData rdo = new RedisData(Bucket.newBucketFromStringMap(map)); assertThat(converter.read(Person.class, rdo).nicknames).containsExactly("dragon reborn", "car'a'carn", - "lews therin"); + "lews therin"); } @Test // DATAREDIS-768 @@ -408,7 +432,7 @@ class MappingRedisConverterUnitTests { RedisTestData target = write(rand); assertThat(target).containsEntry("physicalAttributes.[hair-color]", "red") // - .containsEntry("physicalAttributes.[eye-color]", "grey"); + .containsEntry("physicalAttributes.[eye-color]", "grey"); } @Test // DATAREDIS-425 @@ -425,7 +449,7 @@ class MappingRedisConverterUnitTests { RedisTestData target = write(rand); assertThat(target).containsEntry("coworkers.[0].physicalAttributes.[hair-color]", "red") // - .containsEntry("coworkers.[0].physicalAttributes.[eye-color]", "grey"); + .containsEntry("coworkers.[0].physicalAttributes.[eye-color]", "grey"); } @Test // DATAREDIS-425 @@ -487,7 +511,7 @@ class MappingRedisConverterUnitTests { RedisTestData target = write(source); assertThat(target).containsEntry("decimalMapKeyMapping.[1.7]", "2") // - .containsEntry("decimalMapKeyMapping.[3.1]", "4"); + .containsEntry("decimalMapKeyMapping.[3.1]", "4"); } @Test // DATAREDIS-768 @@ -533,7 +557,7 @@ class MappingRedisConverterUnitTests { RedisTestData target = write(rand); assertThat(target).containsEntry("relatives.[father].firstname", "janduin") // - .containsEntry("relatives.[step-father].firstname", "tam"); + .containsEntry("relatives.[step-father].firstname", "tam"); } @Test // DATAREDIS-425 @@ -617,7 +641,8 @@ class MappingRedisConverterUnitTests { void readsLocalDateTimeValuesCorrectly() { Person target = converter.read(Person.class, - new RedisData(Bucket.newBucketFromStringMap(Collections.singletonMap("localDateTime", "2016-02-19T10:18:01")))); + new RedisData( + Bucket.newBucketFromStringMap(Collections.singletonMap("localDateTime", "2016-02-19T10:18:01")))); assertThat(target.localDateTime).isEqualTo(LocalDateTime.parse("2016-02-19T10:18:01")); } @@ -634,7 +659,7 @@ class MappingRedisConverterUnitTests { void readsLocalDateValuesCorrectly() { Person target = converter.read(Person.class, - new RedisData(Bucket.newBucketFromStringMap(Collections.singletonMap("localDate", "2016-02-19")))); + new RedisData(Bucket.newBucketFromStringMap(Collections.singletonMap("localDate", "2016-02-19")))); assertThat(target.localDate).isEqualTo(LocalDate.parse("2016-02-19")); } @@ -651,7 +676,7 @@ class MappingRedisConverterUnitTests { void readsLocalTimeValuesCorrectly() { Person target = converter.read(Person.class, - new RedisData(Bucket.newBucketFromStringMap(Collections.singletonMap("localTime", "11:12")))); + new RedisData(Bucket.newBucketFromStringMap(Collections.singletonMap("localTime", "11:12")))); assertThat(target.localTime).isEqualTo(LocalTime.parse("11:12:00")); } @@ -668,7 +693,8 @@ class MappingRedisConverterUnitTests { void readsZonedDateTimeValuesCorrectly() { Person target = converter.read(Person.class, new RedisData(Bucket - .newBucketFromStringMap(Collections.singletonMap("zonedDateTime", "2007-12-03T10:15:30+01:00[Europe/Paris]")))); + .newBucketFromStringMap( + Collections.singletonMap("zonedDateTime", "2007-12-03T10:15:30+01:00[Europe/Paris]")))); assertThat(target.zonedDateTime).isEqualTo(ZonedDateTime.parse("2007-12-03T10:15:30+01:00[Europe/Paris]")); } @@ -685,7 +711,8 @@ class MappingRedisConverterUnitTests { void readsInstantValuesCorrectly() { Person target = converter.read(Person.class, - new RedisData(Bucket.newBucketFromStringMap(Collections.singletonMap("instant", "2007-12-03T10:15:30.01Z")))); + new RedisData( + Bucket.newBucketFromStringMap(Collections.singletonMap("instant", "2007-12-03T10:15:30.01Z")))); assertThat(target.instant).isEqualTo(Instant.parse("2007-12-03T10:15:30.01Z")); } @@ -722,7 +749,7 @@ class MappingRedisConverterUnitTests { void readsDurationValuesCorrectly() { Person target = converter.read(Person.class, - new RedisData(Bucket.newBucketFromStringMap(Collections.singletonMap("duration", "PT51H4M")))); + new RedisData(Bucket.newBucketFromStringMap(Collections.singletonMap("duration", "PT51H4M")))); assertThat(target.duration).isEqualTo(Duration.parse("P2DT3H4M")); } @@ -739,7 +766,7 @@ class MappingRedisConverterUnitTests { void readsPeriodValuesCorrectly() { Person target = converter.read(Person.class, - new RedisData(Bucket.newBucketFromStringMap(Collections.singletonMap("period", "P1Y2M25D")))); + new RedisData(Bucket.newBucketFromStringMap(Collections.singletonMap("period", "P1Y2M25D")))); assertThat(target.period).isEqualTo(Period.parse("P1Y2M25D")); } @@ -756,7 +783,7 @@ class MappingRedisConverterUnitTests { void readsEnumValuesCorrectly() { Person target = converter.read(Person.class, - new RedisData(Bucket.newBucketFromStringMap(Collections.singletonMap("gender", "FEMALE")))); + new RedisData(Bucket.newBucketFromStringMap(Collections.singletonMap("gender", "FEMALE")))); assertThat(target.gender).isEqualTo(Gender.FEMALE); } @@ -773,7 +800,7 @@ class MappingRedisConverterUnitTests { void readsBooleanValuesCorrectly() { Person target = converter.read(Person.class, - new RedisData(Bucket.newBucketFromStringMap(Collections.singletonMap("alive", "1")))); + new RedisData(Bucket.newBucketFromStringMap(Collections.singletonMap("alive", "1")))); assertThat(target.alive).isEqualTo(Boolean.TRUE); } @@ -782,7 +809,7 @@ class MappingRedisConverterUnitTests { void readsStringBooleanValuesCorrectly() { Person target = converter.read(Person.class, - new RedisData(Bucket.newBucketFromStringMap(Collections.singletonMap("alive", "true")))); + new RedisData(Bucket.newBucketFromStringMap(Collections.singletonMap("alive", "true")))); assertThat(target.alive).isEqualTo(Boolean.TRUE); } @@ -807,7 +834,8 @@ class MappingRedisConverterUnitTests { Date date = cal.getTime(); Person target = converter.read(Person.class, new RedisData( - Bucket.newBucketFromStringMap(Collections.singletonMap("birthdate", Long.valueOf(date.getTime()).toString())))); + Bucket.newBucketFromStringMap( + Collections.singletonMap("birthdate", Long.valueOf(date.getTime()).toString())))); assertThat(target.birthdate).isEqualTo(date); } @@ -824,8 +852,8 @@ class MappingRedisConverterUnitTests { RedisTestData target = write(rand); assertThat(target).containsEntry("location", "locations:1") // - .without("location.id") // - .without("location.name"); + .without("location.id") // + .without("location.name"); } @Test // DATAREDIS-425 @@ -840,7 +868,7 @@ class MappingRedisConverterUnitTests { locationMap.put("name", location.name); when(resolverMock.resolveReference(eq("1"), eq("locations"))) - .thenReturn(Bucket.newBucketFromStringMap(locationMap).rawMap()); + .thenReturn(Bucket.newBucketFromStringMap(locationMap).rawMap()); Map map = new LinkedHashMap<>(); map.put("location", "locations:1"); @@ -863,8 +891,8 @@ class MappingRedisConverterUnitTests { rand.coworkers = Collections.singletonList(egwene); assertThat(write(rand)).containsEntry("coworkers.[0].location", "locations:1") // - .without("coworkers.[0].location.id") // - .without("coworkers.[0].location.name"); + .without("coworkers.[0].location.id") // + .without("coworkers.[0].location.name"); } @Test // DATAREDIS-425 @@ -879,7 +907,7 @@ class MappingRedisConverterUnitTests { locationMap.put("name", location.name); when(resolverMock.resolveReference(eq("1"), eq("locations"))) - .thenReturn(Bucket.newBucketFromStringMap(locationMap).rawMap()); + .thenReturn(Bucket.newBucketFromStringMap(locationMap).rawMap()); Map map = new LinkedHashMap<>(); map.put("coworkers.[0].location", "locations:1"); @@ -909,8 +937,8 @@ class MappingRedisConverterUnitTests { RedisTestData target = write(rand); assertThat(target).containsEntry("visited.[0]", "locations:1") // - .containsEntry("visited.[1]", "locations:2") // - .containsEntry("visited.[2]", "locations:3"); + .containsEntry("visited.[1]", "locations:2") // + .containsEntry("visited.[2]", "locations:3"); } @Test // DATAREDIS-425 @@ -943,11 +971,11 @@ class MappingRedisConverterUnitTests { Bucket.newBucketFromStringMap(tearMap).rawMap(); when(resolverMock.resolveReference(eq("1"), eq("locations"))) - .thenReturn(Bucket.newBucketFromStringMap(tarValonMap).rawMap()); + .thenReturn(Bucket.newBucketFromStringMap(tarValonMap).rawMap()); when(resolverMock.resolveReference(eq("2"), eq("locations"))) - .thenReturn(Bucket.newBucketFromStringMap(falmeMap).rawMap()); + .thenReturn(Bucket.newBucketFromStringMap(falmeMap).rawMap()); when(resolverMock.resolveReference(eq("3"), eq("locations"))) - .thenReturn(Bucket.newBucketFromStringMap(tearMap).rawMap()); + .thenReturn(Bucket.newBucketFromStringMap(tearMap).rawMap()); Map map = new LinkedHashMap<>(); map.put("visited.[0]", "locations:1"); @@ -985,7 +1013,7 @@ class MappingRedisConverterUnitTests { void writeShouldConsiderKeyspaceConfiguration() { this.converter.getMappingContext().getMappingConfiguration().getKeyspaceConfiguration() - .addKeyspaceSettings(new KeyspaceSettings(Address.class, "o_O")); + .addKeyspaceSettings(new KeyspaceSettings(Address.class, "o_O")); Address address = new Address(); address.city = "Tear"; @@ -1000,7 +1028,7 @@ class MappingRedisConverterUnitTests { assignment.setTimeToLive(5L); this.converter.getMappingContext().getMappingConfiguration().getKeyspaceConfiguration() - .addKeyspaceSettings(assignment); + .addKeyspaceSettings(assignment); Address address = new Address(); address.city = "Tear"; @@ -1012,7 +1040,7 @@ class MappingRedisConverterUnitTests { void writeShouldHonorCustomConversionOnRootType() { RedisCustomConversions customConversions = new RedisCustomConversions( - Collections.singletonList(new AddressToBytesConverter())); + Collections.singletonList(new AddressToBytesConverter())); RedisMappingContext mappingContext = new RedisMappingContext(); mappingContext.setSimpleTypeHolder(customConversions.getSimpleTypeHolder()); @@ -1032,7 +1060,7 @@ class MappingRedisConverterUnitTests { void writeShouldHonorCustomConversionOnNestedType() { RedisCustomConversions customConversions = new RedisCustomConversions( - Collections.singletonList(new AddressToBytesConverter())); + Collections.singletonList(new AddressToBytesConverter())); RedisMappingContext mappingContext = new RedisMappingContext(); mappingContext.setSimpleTypeHolder(customConversions.getSimpleTypeHolder()); @@ -1054,7 +1082,7 @@ class MappingRedisConverterUnitTests { this.converter = new MappingRedisConverter(null, null, resolverMock); this.converter - .setCustomConversions(new RedisCustomConversions(Collections.singletonList(new AddressToBytesConverter()))); + .setCustomConversions(new RedisCustomConversions(Collections.singletonList(new AddressToBytesConverter()))); this.converter.afterPropertiesSet(); Address address = new Address(); @@ -1062,7 +1090,7 @@ class MappingRedisConverterUnitTests { rand.address = address; assertThat(write(rand).getRedisData().getIndexedData()) - .contains(new SimpleIndexedPropertyValue(KEYSPACE_PERSON, "address.country", "andor")); + .contains(new SimpleIndexedPropertyValue(KEYSPACE_PERSON, "address.country", "andor")); } @Test // DATAREDIS-425 @@ -1070,7 +1098,7 @@ class MappingRedisConverterUnitTests { this.converter = new MappingRedisConverter(new RedisMappingContext(), null, resolverMock); this.converter - .setCustomConversions(new RedisCustomConversions(Collections.singletonList(new AddressToBytesConverter()))); + .setCustomConversions(new RedisCustomConversions(Collections.singletonList(new AddressToBytesConverter()))); this.converter.afterPropertiesSet(); Address address = new Address(); @@ -1086,7 +1114,7 @@ class MappingRedisConverterUnitTests { this.converter = new MappingRedisConverter(null, null, resolverMock); this.converter - .setCustomConversions(new RedisCustomConversions(Collections.singletonList(new BytesToAddressConverter()))); + .setCustomConversions(new RedisCustomConversions(Collections.singletonList(new BytesToAddressConverter()))); this.converter.afterPropertiesSet(); Map map = new LinkedHashMap<>(); @@ -1103,7 +1131,7 @@ class MappingRedisConverterUnitTests { this.converter = new MappingRedisConverter(new RedisMappingContext(), null, resolverMock); this.converter - .setCustomConversions(new RedisCustomConversions(Collections.singletonList(new BytesToAddressConverter()))); + .setCustomConversions(new RedisCustomConversions(Collections.singletonList(new BytesToAddressConverter()))); this.converter.afterPropertiesSet(); Map map = new LinkedHashMap<>(); @@ -1121,14 +1149,14 @@ class MappingRedisConverterUnitTests { this.converter = new MappingRedisConverter(new RedisMappingContext(), null, resolverMock); this.converter - .setCustomConversions(new RedisCustomConversions(Collections.singletonList(new BytesToAddressConverter()))); + .setCustomConversions(new RedisCustomConversions(Collections.singletonList(new BytesToAddressConverter()))); this.converter.afterPropertiesSet(); Map map = new LinkedHashMap<>(); map.put("address", "{\"city\":\"unknown\",\"country\":\"Tel'aran'rhiod\"}"); PersonWithConstructorAndAddress target = converter.read(PersonWithConstructorAndAddress.class, - new RedisData(Bucket.newBucketFromStringMap(map))); + new RedisData(Bucket.newBucketFromStringMap(map))); assertThat(target.address).isNotNull(); assertThat(target.address.city).isEqualTo("unknown"); @@ -1159,7 +1187,7 @@ class MappingRedisConverterUnitTests { this.converter = new MappingRedisConverter(new RedisMappingContext(), null, resolverMock); this.converter - .setCustomConversions(new RedisCustomConversions(Collections.singletonList(new SpeciesToMapConverter()))); + .setCustomConversions(new RedisCustomConversions(Collections.singletonList(new SpeciesToMapConverter()))); this.converter.afterPropertiesSet(); Species myrddraal = new Species(); @@ -1167,7 +1195,7 @@ class MappingRedisConverterUnitTests { myrddraal.alsoKnownAs = Arrays.asList("halfmen", "fades", "neverborn"); assertThat(write(myrddraal)).containsEntry("species-name", "myrddraal").containsEntry("species-nicknames", - "halfmen,fades,neverborn"); + "halfmen,fades,neverborn"); } @Test // DATAREDIS-425 @@ -1175,7 +1203,7 @@ class MappingRedisConverterUnitTests { this.converter = new MappingRedisConverter(null, null, resolverMock); this.converter - .setCustomConversions(new RedisCustomConversions(Collections.singletonList(new SpeciesToMapConverter()))); + .setCustomConversions(new RedisCustomConversions(Collections.singletonList(new SpeciesToMapConverter()))); this.converter.afterPropertiesSet(); rand.species = new Species(); @@ -1189,7 +1217,7 @@ class MappingRedisConverterUnitTests { this.converter = new MappingRedisConverter(new RedisMappingContext(), null, resolverMock); this.converter - .setCustomConversions(new RedisCustomConversions(Collections.singletonList(new MapToSpeciesConverter()))); + .setCustomConversions(new RedisCustomConversions(Collections.singletonList(new MapToSpeciesConverter()))); this.converter.afterPropertiesSet(); Map map = new LinkedHashMap<>(); map.put("species-name", "trolloc"); @@ -1205,7 +1233,7 @@ class MappingRedisConverterUnitTests { this.converter = new MappingRedisConverter(null, null, resolverMock); this.converter - .setCustomConversions(new RedisCustomConversions(Collections.singletonList(new MapToSpeciesConverter()))); + .setCustomConversions(new RedisCustomConversions(Collections.singletonList(new MapToSpeciesConverter()))); this.converter.afterPropertiesSet(); Map map = new LinkedHashMap<>(); @@ -1222,7 +1250,7 @@ class MappingRedisConverterUnitTests { this.converter = new MappingRedisConverter(new RedisMappingContext(), null, resolverMock); this.converter - .setCustomConversions(new RedisCustomConversions(Collections.singletonList(new SpeciesToMapConverter()))); + .setCustomConversions(new RedisCustomConversions(Collections.singletonList(new SpeciesToMapConverter()))); this.converter.afterPropertiesSet(); TheWheelOfTime twot = new TheWheelOfTime(); @@ -1234,7 +1262,7 @@ class MappingRedisConverterUnitTests { twot.species.add(myrddraal); assertThat(write(twot)).containsEntry("species.[0].species-name", "myrddraal") - .containsEntry("species.[0].species-nicknames", "halfmen,fades,neverborn"); + .containsEntry("species.[0].species-nicknames", "halfmen,fades,neverborn"); } @Test // DATAREDIS-425 @@ -1242,7 +1270,7 @@ class MappingRedisConverterUnitTests { this.converter = new MappingRedisConverter(null, null, resolverMock); this.converter - .setCustomConversions(new RedisCustomConversions(Collections.singletonList(new MapToSpeciesConverter()))); + .setCustomConversions(new RedisCustomConversions(Collections.singletonList(new MapToSpeciesConverter()))); this.converter.afterPropertiesSet(); Map map = new LinkedHashMap<>(); @@ -1263,7 +1291,7 @@ class MappingRedisConverterUnitTests { source.arrayOfSimpleTypes = new String[] { "rand", "mat", "perrin" }; assertThat(write(source)).containsEntry("arrayOfSimpleTypes.[0]", "rand") - .containsEntry("arrayOfSimpleTypes.[1]", "mat").containsEntry("arrayOfSimpleTypes.[2]", "perrin"); + .containsEntry("arrayOfSimpleTypes.[1]", "mat").containsEntry("arrayOfSimpleTypes.[2]", "perrin"); } @Test // DATAREDIS-492 @@ -1328,10 +1356,10 @@ class MappingRedisConverterUnitTests { source.arrayOfCompexTypes = new Species[] { trolloc, myrddraal }; assertThat(write(source)).containsEntry("arrayOfCompexTypes.[0].name", "trolloc") // - .containsEntry("arrayOfCompexTypes.[1].name", "myrddraal") // - .containsEntry("arrayOfCompexTypes.[1].alsoKnownAs.[0]", "halfmen") // - .containsEntry("arrayOfCompexTypes.[1].alsoKnownAs.[1]", "fades") // - .containsEntry("arrayOfCompexTypes.[1].alsoKnownAs.[2]", "neverborn"); + .containsEntry("arrayOfCompexTypes.[1].name", "myrddraal") // + .containsEntry("arrayOfCompexTypes.[1].alsoKnownAs.[0]", "halfmen") // + .containsEntry("arrayOfCompexTypes.[1].alsoKnownAs.[1]", "fades") // + .containsEntry("arrayOfCompexTypes.[1].alsoKnownAs.[2]", "neverborn"); } @Test // DATAREDIS-492 @@ -1363,11 +1391,11 @@ class MappingRedisConverterUnitTests { source.arrayOfObject = new Object[] { "rand", trolloc, 100L }; assertThat(write(source)).containsEntry("arrayOfObject.[0]", "rand") // - .containsEntry("arrayOfObject.[0]._class", "java.lang.String") - .containsEntry("arrayOfObject.[1]._class", Species.class.getName()) // - .containsEntry("arrayOfObject.[1].name", "trolloc") // - .containsEntry("arrayOfObject.[2]._class", "java.lang.Long") // - .containsEntry("arrayOfObject.[2]", "100"); + .containsEntry("arrayOfObject.[0]._class", "java.lang.String") + .containsEntry("arrayOfObject.[1]._class", Species.class.getName()) // + .containsEntry("arrayOfObject.[1].name", "trolloc") // + .containsEntry("arrayOfObject.[2]._class", "java.lang.Long") // + .containsEntry("arrayOfObject.[2]", "100"); } @Test // DATAREDIS-489 @@ -1424,7 +1452,8 @@ class MappingRedisConverterUnitTests { RedisTestData bucket = write(sample); - assertThat(bucket).containsEntry("map.[string]", "bar").containsEntry("map.[string]._class", "java.lang.String"); + assertThat(bucket).containsEntry("map.[string]", "bar") + .containsEntry("map.[string]._class", "java.lang.String"); assertThat(bucket).containsEntry("map.[long]", "1").containsEntry("map.[long]._class", "java.lang.Long"); assertThat(bucket).containsEntry("map.[date]._class", "java.util.Date"); } @@ -1508,8 +1537,9 @@ class MappingRedisConverterUnitTests { WithArrays source = new WithArrays(); source.arrayOfPrimitives = new int[] { 1, 2, 3 }; - assertThat(write(source)).containsEntry("arrayOfPrimitives.[0]", "1").containsEntry("arrayOfPrimitives.[1]", "2") - .containsEntry("arrayOfPrimitives.[2]", "3"); + assertThat(write(source)).containsEntry("arrayOfPrimitives.[0]", "1") + .containsEntry("arrayOfPrimitives.[1]", "2") + .containsEntry("arrayOfPrimitives.[2]", "3"); } @Test // DATAREDIS-471 @@ -1551,7 +1581,7 @@ class MappingRedisConverterUnitTests { void writeShouldWritePartialUpdateFromSetByteArrayValueCorrectly() { PartialUpdate update = PartialUpdate.newPartialUpdate(42, WithArrays.class).set("avatar", - "foo-bar-baz".getBytes()); + "foo-bar-baz".getBytes()); assertThat(write(update)).containsEntry("avatar", "foo-bar-baz"); } @@ -1588,7 +1618,7 @@ class MappingRedisConverterUnitTests { void writeShouldWritePartialUpdatePathWithSimpleListValueCorrectly() { PartialUpdate update = new PartialUpdate<>("123", Person.class).set("nicknames", - Arrays.asList("dragon", "lews")); + Arrays.asList("dragon", "lews")); assertThat(write(update)).containsEntry("nicknames.[0]", "dragon").containsEntry("nicknames.[1]", "lews"); } @@ -1604,10 +1634,11 @@ class MappingRedisConverterUnitTests { perrin.firstname = "perrin"; PartialUpdate update = new PartialUpdate<>("123", Person.class).set("coworkers", - Arrays.asList(mat, perrin)); + Arrays.asList(mat, perrin)); - assertThat(write(update)).containsEntry("coworkers.[0].firstname", "mat").containsEntry("coworkers.[0].age", "24") - .containsEntry("coworkers.[1].firstname", "perrin"); + assertThat(write(update)).containsEntry("coworkers.[0].firstname", "mat") + .containsEntry("coworkers.[0].age", "24") + .containsEntry("coworkers.[1].firstname", "perrin"); } @Test // DATAREDIS-471 @@ -1627,7 +1658,8 @@ class MappingRedisConverterUnitTests { PartialUpdate update = new PartialUpdate<>("123", Person.class).set("coworkers", mat); - assertThat(write(update)).containsEntry("coworkers.[0].firstname", "mat").containsEntry("coworkers.[0].age", "24"); + assertThat(write(update)).containsEntry("coworkers.[0].firstname", "mat") + .containsEntry("coworkers.[0].age", "24"); } @Test // DATAREDIS-471 @@ -1647,14 +1679,15 @@ class MappingRedisConverterUnitTests { PartialUpdate update = new PartialUpdate<>("123", Person.class).set("coworkers.[5]", mat); - assertThat(write(update)).containsEntry("coworkers.[5].firstname", "mat").containsEntry("coworkers.[5].age", "24"); + assertThat(write(update)).containsEntry("coworkers.[5].firstname", "mat") + .containsEntry("coworkers.[5].age", "24"); } @Test // DATAREDIS-471 void writeShouldWritePartialUpdatePathWithSimpleMapValueCorrectly() { PartialUpdate update = new PartialUpdate<>("123", Person.class).set("physicalAttributes", - Collections.singletonMap("eye-color", "grey")); + Collections.singletonMap("eye-color", "grey")); assertThat(write(update)).containsEntry("physicalAttributes.[eye-color]", "grey"); } @@ -1667,17 +1700,17 @@ class MappingRedisConverterUnitTests { tam.alive = false; PartialUpdate update = new PartialUpdate<>("123", Person.class).set("relatives", - Collections.singletonMap("father", tam)); + Collections.singletonMap("father", tam)); assertThat(write(update)).containsEntry("relatives.[father].firstname", "tam") - .containsEntry("relatives.[father].alive", "0"); + .containsEntry("relatives.[father].alive", "0"); } @Test // DATAREDIS-471 void writeShouldWritePartialUpdatePathWithSimpleMapValueWhenNotPassedInAsCollectionCorrectly() { PartialUpdate update = new PartialUpdate<>("123", Person.class).set("physicalAttributes", - Collections.singletonMap("eye-color", "grey").entrySet().iterator().next()); + Collections.singletonMap("eye-color", "grey").entrySet().iterator().next()); assertThat(write(update)).containsEntry("physicalAttributes.[eye-color]", "grey"); } @@ -1690,17 +1723,17 @@ class MappingRedisConverterUnitTests { tam.alive = false; PartialUpdate update = new PartialUpdate<>("123", Person.class).set("relatives", - Collections.singletonMap("father", tam).entrySet().iterator().next()); + Collections.singletonMap("father", tam).entrySet().iterator().next()); assertThat(write(update)).containsEntry("relatives.[father].firstname", "tam") - .containsEntry("relatives.[father].alive", "0"); + .containsEntry("relatives.[father].alive", "0"); } @Test // DATAREDIS-471 void writeShouldWritePartialUpdatePathWithSimpleMapValueWhenNotPassedInAsCollectionWithPositionalParameterCorrectly() { PartialUpdate update = new PartialUpdate<>("123", Person.class).set("physicalAttributes.[eye-color]", - "grey"); + "grey"); assertThat(write(update)).containsEntry("physicalAttributes.[eye-color]", "grey"); } @@ -1708,7 +1741,8 @@ class MappingRedisConverterUnitTests { @Test // DATAREDIS-471 void writeShouldWritePartialUpdatePathWithSimpleMapValueOnNestedElementCorrectly() { - PartialUpdate update = new PartialUpdate<>("123", Person.class).set("relatives.[father].firstname", "tam"); + PartialUpdate update = new PartialUpdate<>("123", Person.class).set("relatives.[father].firstname", + "tam"); assertThat(write(update)).containsEntry("relatives.[father].firstname", "tam"); } @@ -1726,7 +1760,7 @@ class MappingRedisConverterUnitTests { this.converter = new MappingRedisConverter(null, null, resolverMock); this.converter - .setCustomConversions(new RedisCustomConversions(Collections.singletonList(new AddressToBytesConverter()))); + .setCustomConversions(new RedisCustomConversions(Collections.singletonList(new AddressToBytesConverter()))); this.converter.afterPropertiesSet(); Address address = new Address(); @@ -1749,11 +1783,13 @@ class MappingRedisConverterUnitTests { tear.id = "2"; tear.name = "city of tear"; - PartialUpdate update = new PartialUpdate<>("123", Person.class).set("visited", Arrays.asList(tar, tear)); + PartialUpdate update = new PartialUpdate<>("123", Person.class).set("visited", + Arrays.asList(tar, tear)); - assertThat(write(update)).containsEntry("visited.[0]", "locations:1").containsEntry("visited.[1]", "locations:2") // - .without("visited.id") // - .without("visited.name"); + assertThat(write(update)).containsEntry("visited.[0]", "locations:1") + .containsEntry("visited.[1]", "locations:2") // + .without("visited.id") // + .without("visited.name"); } @Test // DATAREDIS-471 @@ -1764,65 +1800,65 @@ class MappingRedisConverterUnitTests { location.name = "tar valon"; PartialUpdate update = new PartialUpdate<>("123", Person.class) // - .set("location", location); + .set("location", location); assertThat(write(update)).containsEntry("location", "locations:1") // - .without("location.id") // - .without("location.name"); + .without("location.id") // + .without("location.name"); } @Test // DATAREDIS-471 void writeShouldThrowExceptionForUpdateValueNotAssignableToDomainTypeProperty() { PartialUpdate update = new PartialUpdate<>("123", Person.class) // - .set("age", "twenty-four"); + .set("age", "twenty-four"); assertThatExceptionOfType(MappingException.class).isThrownBy(() -> write(update)) - .withMessageContaining("java.lang.String cannot be assigned"); + .withMessageContaining("java.lang.String cannot be assigned"); } @Test // DATAREDIS-471 void writeShouldThrowExceptionForUpdateCollectionValueNotAssignableToDomainTypeProperty() { PartialUpdate update = new PartialUpdate<>("123", Person.class) // - .set("coworkers.[0]", "buh buh the bear"); + .set("coworkers.[0]", "buh buh the bear"); assertThatExceptionOfType(MappingException.class).isThrownBy(() -> write(update)) - .withMessageContaining("java.lang.String cannot be assigned").withMessageContaining(Person.class.getName()) - .withMessageContaining("coworkers.[0]"); + .withMessageContaining("java.lang.String cannot be assigned").withMessageContaining(Person.class.getName()) + .withMessageContaining("coworkers.[0]"); } @Test // DATAREDIS-471 void writeShouldThrowExceptionForUpdateValueInCollectionNotAssignableToDomainTypeProperty() { PartialUpdate update = new PartialUpdate<>("123", Person.class) // - .set("coworkers", Collections.singletonList("foo")); + .set("coworkers", Collections.singletonList("foo")); assertThatExceptionOfType(MappingException.class).isThrownBy(() -> write(update)) - .withMessageContaining("java.lang.String cannot be assigned").withMessageContaining(Person.class.getName()) - .withMessageContaining("coworkers"); + .withMessageContaining("java.lang.String cannot be assigned").withMessageContaining(Person.class.getName()) + .withMessageContaining("coworkers"); } @Test // DATAREDIS-471 void writeShouldThrowExceptionForUpdateMapValueNotAssignableToDomainTypeProperty() { PartialUpdate update = new PartialUpdate<>("123", Person.class) // - .set("relatives.[father]", "buh buh the bear"); + .set("relatives.[father]", "buh buh the bear"); assertThatExceptionOfType(MappingException.class).isThrownBy(() -> write(update)) - .withMessageContaining("java.lang.String cannot be assigned").withMessageContaining(Person.class.getName()) - .withMessageContaining("relatives.[father]"); + .withMessageContaining("java.lang.String cannot be assigned").withMessageContaining(Person.class.getName()) + .withMessageContaining("relatives.[father]"); } @Test // DATAREDIS-471 void writeShouldThrowExceptionForUpdateValueInMapNotAssignableToDomainTypeProperty() { PartialUpdate update = new PartialUpdate<>("123", Person.class) // - .set("relatives", Collections.singletonMap("father", "buh buh the bear")); + .set("relatives", Collections.singletonMap("father", "buh buh the bear")); assertThatExceptionOfType(MappingException.class).isThrownBy(() -> write(update)) - .withMessageContaining("java.lang.String cannot be assigned").withMessageContaining(Person.class.getName()) - .withMessageContaining("relatives.[father]"); + .withMessageContaining("java.lang.String cannot be assigned").withMessageContaining(Person.class.getName()) + .withMessageContaining("relatives.[father]"); } @Test // DATAREDIS-875 @@ -1895,7 +1931,8 @@ class MappingRedisConverterUnitTests { this.converter = new MappingRedisConverter(null, null, resolverMock); this.converter - .setCustomConversions(new RedisCustomConversions(Collections.singletonList(new AccountInfoToBytesConverter()))); + .setCustomConversions( + new RedisCustomConversions(Collections.singletonList(new AccountInfoToBytesConverter()))); this.converter.afterPropertiesSet(); AccountInfo accountInfo = new AccountInfo(); @@ -1911,7 +1948,8 @@ class MappingRedisConverterUnitTests { this.converter = new MappingRedisConverter(null, null, resolverMock); this.converter - .setCustomConversions(new RedisCustomConversions(Collections.singletonList(new BytesToAccountInfoConverter()))); + .setCustomConversions( + new RedisCustomConversions(Collections.singletonList(new BytesToAccountInfoConverter()))); this.converter.afterPropertiesSet(); Bucket bucket = new Bucket(); @@ -1934,11 +1972,11 @@ class MappingRedisConverterUnitTests { generic.entity = new User("hello"); assertThat(write(generic)).hasSize(3) // - .containsEntry("_class", - "org.springframework.data.redis.core.convert.MappingRedisConverterUnitTests$WithGenericEntity") - .containsEntry("entity.name", "hello") // - .containsEntry("entity._class", - "org.springframework.data.redis.core.convert.MappingRedisConverterUnitTests$User"); + .containsEntry("_class", + "org.springframework.data.redis.core.convert.MappingRedisConverterUnitTests$WithGenericEntity") + .containsEntry("entity.name", "hello") // + .containsEntry("entity._class", + "org.springframework.data.redis.core.convert.MappingRedisConverterUnitTests$User"); } @Test // GH-2349 @@ -1947,7 +1985,7 @@ class MappingRedisConverterUnitTests { Bucket bucket = new Bucket(); bucket.put("entity.name", "hello".getBytes()); bucket.put("entity._class", - "org.springframework.data.redis.core.convert.MappingRedisConverterUnitTests$User".getBytes()); + "org.springframework.data.redis.core.convert.MappingRedisConverterUnitTests$User".getBytes()); RedisData redisData = new RedisData(bucket); redisData.setKeyspace(KEYSPACE_ACCOUNT); @@ -1961,16 +1999,16 @@ class MappingRedisConverterUnitTests { @Test // DATAREDIS-1175 @EnabledOnJre(JRE.JAVA_8) - // FIXME: https://github.com/spring-projects/spring-data-redis/issues/2168 + // FIXME: https://github.com/spring-projects/spring-data-redis/issues/2168 void writePlainList() { List source = Arrays.asList("Hello", "stream", "message", 100L); RedisTestData target = write(source); assertThat(target).containsEntry("[0]", "Hello") // - .containsEntry("[1]", "stream") // - .containsEntry("[2]", "message") // - .containsEntry("[3]", "100"); + .containsEntry("[1]", "stream") // + .containsEntry("[2]", "message") // + .containsEntry("[3]", "100"); } @Test // DATAREDIS-1175 @@ -2012,8 +2050,8 @@ class MappingRedisConverterUnitTests { mapper = new ObjectMapper(); mapper.setVisibility(mapper.getSerializationConfig().getDefaultVisibilityChecker() - .withFieldVisibility(Visibility.ANY).withGetterVisibility(Visibility.NONE) - .withSetterVisibility(Visibility.NONE).withCreatorVisibility(Visibility.NONE)); + .withFieldVisibility(Visibility.ANY).withGetterVisibility(Visibility.NONE) + .withSetterVisibility(Visibility.NONE).withCreatorVisibility(Visibility.NONE)); serializer = new Jackson2JsonRedisSerializer<>(Address.class); serializer.setObjectMapper(mapper); @@ -2040,7 +2078,7 @@ class MappingRedisConverterUnitTests { map.put("species-name", source.name.getBytes(Charset.forName("UTF-8"))); } map.put("species-nicknames", - StringUtils.collectionToCommaDelimitedString(source.alsoKnownAs).getBytes(Charset.forName("UTF-8"))); + StringUtils.collectionToCommaDelimitedString(source.alsoKnownAs).getBytes(Charset.forName("UTF-8"))); return map; } } @@ -2062,7 +2100,8 @@ class MappingRedisConverterUnitTests { } if (source.containsKey("species-nicknames")) { species.alsoKnownAs = Arrays.asList(StringUtils - .commaDelimitedListToStringArray(new String(source.get("species-nicknames"), Charset.forName("UTF-8")))); + .commaDelimitedListToStringArray( + new String(source.get("species-nicknames"), Charset.forName("UTF-8")))); } return species; } @@ -2078,8 +2117,8 @@ class MappingRedisConverterUnitTests { mapper = new ObjectMapper(); mapper.setVisibility(mapper.getSerializationConfig().getDefaultVisibilityChecker() - .withFieldVisibility(Visibility.ANY).withGetterVisibility(Visibility.NONE) - .withSetterVisibility(Visibility.NONE).withCreatorVisibility(Visibility.NONE)); + .withFieldVisibility(Visibility.ANY).withGetterVisibility(Visibility.NONE) + .withSetterVisibility(Visibility.NONE).withCreatorVisibility(Visibility.NONE)); serializer = new Jackson2JsonRedisSerializer<>(Address.class); serializer.setObjectMapper(mapper); @@ -2098,7 +2137,7 @@ class MappingRedisConverterUnitTests { public byte[] convert(AccountInfo accountInfo) { StringBuilder resp = new StringBuilder(); resp.append(accountInfo.getId()).append("|").append(accountInfo.getAccount()).append("|") - .append(accountInfo.getAccountName()); + .append(accountInfo.getAccountName()); return resp.toString().getBytes(StandardCharsets.UTF_8); } } @@ -2118,12 +2157,21 @@ class MappingRedisConverterUnitTests { } static class WithGenericEntity { + T entity; } - @AllArgsConstructor static class User { - String name; - } + private String name; + + public User(String name) { + this.name = name; + } + + @Override + public String toString() { + return this.name; + } + } } diff --git a/src/test/java/org/springframework/data/redis/mapping/Jackson2HashMapperFlatteningUnitTests.java b/src/test/java/org/springframework/data/redis/mapping/Jackson2HashMapperFlatteningUnitTests.java index 786f89916..deacc0408 100644 --- a/src/test/java/org/springframework/data/redis/mapping/Jackson2HashMapperFlatteningUnitTests.java +++ b/src/test/java/org/springframework/data/redis/mapping/Jackson2HashMapperFlatteningUnitTests.java @@ -25,8 +25,6 @@ import org.junit.jupiter.api.Test; import org.springframework.data.redis.hash.Jackson2HashMapper; -import lombok.Data; - /** * @author Christoph Strobl * @author John Blum @@ -49,13 +47,20 @@ public class Jackson2HashMapperFlatteningUnitTests extends Jackson2HashMapperUni Session session = (Session) getMapper().fromHash(hash); assertThat(session).isNotNull(); - assertThat(session.getLastAccessed()).isEqualTo(LocalDateTime.of(2023, Month.JUNE, 5, + assertThat(session.lastAccessed).isEqualTo(LocalDateTime.of(2023, Month.JUNE, 5, 18, 36, 30)); } - - @Data private static class Session { + private LocalDateTime lastAccessed; + + public LocalDateTime getLastAccessed() { + return lastAccessed; + } + + public void setLastAccessed(LocalDateTime lastAccessed) { + this.lastAccessed = lastAccessed; + } } } diff --git a/src/test/java/org/springframework/data/redis/mapping/Jackson2HashMapperIntegrationTests.java b/src/test/java/org/springframework/data/redis/mapping/Jackson2HashMapperIntegrationTests.java index d89cdd2b1..4d6a31a2d 100644 --- a/src/test/java/org/springframework/data/redis/mapping/Jackson2HashMapperIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/mapping/Jackson2HashMapperIntegrationTests.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; +import java.util.Objects; import org.junit.jupiter.api.BeforeEach; @@ -36,15 +37,12 @@ import org.springframework.data.redis.test.extension.RedisStanalone; import org.springframework.data.redis.test.extension.parametrized.MethodSource; import org.springframework.data.redis.test.extension.parametrized.ParameterizedRedisTest; -import lombok.Data; -import lombok.NoArgsConstructor; -import lombok.ToString; - /** * Integration tests for {@link Jackson2HashMapper}. * * @author Christoph Strobl * @author Mark Paluch + * @author John Blum */ @MethodSource("params") public class Jackson2HashMapperIntegrationTests { @@ -109,9 +107,6 @@ public class Jackson2HashMapperIntegrationTests { assertThat(deserializedJonDoe.getPhoneNumber()).containsExactly(9, 7, 1, 5, 5, 5, 4, 1, 8, 2); } - @Data - @ToString(of = "name") - @NoArgsConstructor static class User { static User as(String name) { @@ -121,6 +116,8 @@ public class Jackson2HashMapperIntegrationTests { private String name; private List phoneNumber; + User() { } + User(String name) { this.name = name; } @@ -129,5 +126,46 @@ public class Jackson2HashMapperIntegrationTests { this.phoneNumber = new ArrayList<>(Arrays.asList(numbers)); return this; } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public List getPhoneNumber() { + return this.phoneNumber; + } + + public void setPhoneNumber(List phoneNumber) { + this.phoneNumber = phoneNumber; + } + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof User that)) { + return false; + } + + return Objects.equals(this.getName(), that.getName()) + && Objects.equals(this.getPhoneNumber(), that.getPhoneNumber()); + } + + @Override + public int hashCode() { + return Objects.hash(getName(), getPhoneNumber()); + } + + @Override + public String toString() { + return getName(); + } } } diff --git a/src/test/java/org/springframework/data/redis/mapping/Jackson2HashMapperNonFlatteningUnitTests.java b/src/test/java/org/springframework/data/redis/mapping/Jackson2HashMapperNonFlatteningUnitTests.java index 780901804..0bfd00461 100644 --- a/src/test/java/org/springframework/data/redis/mapping/Jackson2HashMapperNonFlatteningUnitTests.java +++ b/src/test/java/org/springframework/data/redis/mapping/Jackson2HashMapperNonFlatteningUnitTests.java @@ -26,8 +26,6 @@ import org.junit.jupiter.api.Test; import org.springframework.data.redis.hash.Jackson2HashMapper; -import lombok.Data; - /** * @author Christoph Strobl * @author John Blum @@ -50,12 +48,20 @@ public class Jackson2HashMapperNonFlatteningUnitTests extends Jackson2HashMapper Session session = (Session) getMapper().fromHash(hash); assertThat(session).isNotNull(); - assertThat(session.getLastAccessed()).isEqualTo(LocalDateTime.of(2023, Month.JUNE, 5, + assertThat(session.lastAccessed).isEqualTo(LocalDateTime.of(2023, Month.JUNE, 5, 18, 36, 30)); } - @Data private static class Session { + private LocalDateTime lastAccessed; + + public LocalDateTime getLastAccessed() { + return lastAccessed; + } + + public void setLastAccessed(LocalDateTime lastAccessed) { + this.lastAccessed = lastAccessed; + } } } diff --git a/src/test/java/org/springframework/data/redis/mapping/Jackson2HashMapperUnitTests.java b/src/test/java/org/springframework/data/redis/mapping/Jackson2HashMapperUnitTests.java index 3a09778fc..5cf25ac39 100644 --- a/src/test/java/org/springframework/data/redis/mapping/Jackson2HashMapperUnitTests.java +++ b/src/test/java/org/springframework/data/redis/mapping/Jackson2HashMapperUnitTests.java @@ -15,8 +15,6 @@ */ package org.springframework.data.redis.mapping; -import lombok.Data; - import java.math.BigDecimal; import java.math.BigInteger; import java.time.LocalDate; @@ -28,6 +26,7 @@ import java.util.Date; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import org.junit.jupiter.api.Test; @@ -204,23 +203,110 @@ public abstract class Jackson2HashMapperUnitTests extends AbstractHashMapperTest assertBackAndForwardMapping(source); } - @Data public static class WithList { List strings; List objects; List persons; + + public List getStrings() { + return this.strings; + } + + public void setStrings(List strings) { + this.strings = strings; + } + + public List getObjects() { + return this.objects; + } + + public void setObjects(List objects) { + this.objects = objects; + } + + public List getPersons() { + return this.persons; + } + + public void setPersons(List persons) { + this.persons = persons; + } + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof WithList that)) { + return false; + } + + return Objects.equals(this.getObjects(), that.getObjects()) + && Objects.equals(this.getPersons(), that.getPersons()) + && Objects.equals(this.getStrings(), that.getStrings()); + } + + @Override + public int hashCode() { + return Objects.hash(getObjects(), getPersons(), getStrings()); + } } - @Data public static class WithMap { Map strings; Map objects; Map persons; + + public Map getStrings() { + return this.strings; + } + + public void setStrings(Map strings) { + this.strings = strings; + } + + public Map getObjects() { + return this.objects; + } + + public void setObjects(Map objects) { + this.objects = objects; + } + + public Map getPersons() { + return this.persons; + } + + public void setPersons(Map persons) { + this.persons = persons; + } + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof WithMap that)) { + return false; + } + + return Objects.equals(this.getObjects(), that.getObjects()) + && Objects.equals(this.getPersons(), that.getPersons()) + && Objects.equals(this.getStrings(), that.getStrings()); + } + + @Override + public int hashCode() { + return Objects.hash(getObjects(), getPersons(), getStrings()); + } } - @Data private static class WithDates { private String string; @@ -228,16 +314,142 @@ public abstract class Jackson2HashMapperUnitTests extends AbstractHashMapperTest private Calendar calendar; private LocalDate localDate; private LocalDateTime localDateTime; + + public String getString() { + return this.string; + } + + public void setString(String string) { + this.string = string; + } + + public Date getDate() { + return this.date; + } + + public void setDate(Date date) { + this.date = date; + } + + public Calendar getCalendar() { + return this.calendar; + } + + public void setCalendar(Calendar calendar) { + this.calendar = calendar; + } + + public LocalDate getLocalDate() { + return this.localDate; + } + + public void setLocalDate(LocalDate localDate) { + this.localDate = localDate; + } + + public LocalDateTime getLocalDateTime() { + return this.localDateTime; + } + + public void setLocalDateTime(LocalDateTime localDateTime) { + this.localDateTime = localDateTime; + } + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof WithDates that)) { + return false; + } + + return Objects.equals(this.getString(), that.getString()) + && Objects.equals(this.getCalendar(), that.getCalendar()) + && Objects.equals(this.getDate(), that.getDate()) + && Objects.equals(this.getLocalDate(), that.getLocalDate()) + && Objects.equals(this.getLocalDateTime(), that.getLocalDateTime()); + } + + @Override + public int hashCode() { + return Objects.hash(getString(), getCalendar(), getDate(), getLocalDate(), getLocalDateTime()); + } } - @Data private static class WithBigWhatever { + private BigDecimal bigD; private BigInteger bigI; + + public BigDecimal getBigD() { + return this.bigD; + } + + public void setBigD(BigDecimal bigD) { + this.bigD = bigD; + } + + public BigInteger getBigI() { + return this.bigI; + } + + public void setBigI(BigInteger bigI) { + this.bigI = bigI; + } + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof WithBigWhatever that)) { + return false; + } + + return Objects.equals(this.getBigD(), that.getBigD()) + && Objects.equals(this.getBigI(), that.getBigI()); + } + + @Override + public int hashCode() { + return Objects.hash(getBigD(), getBigI()); + } } - @Data public static final class MeFinal { + private String value; + + public String getValue() { + return this.value; + } + + public void setValue(String value) { + this.value = value; + } + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof MeFinal that)) { + return false; + } + + return Objects.equals(this.getValue(), that.getValue()); + } + + @Override + public int hashCode() { + return Objects.hash(getValue()); + } } } diff --git a/src/test/java/org/springframework/data/redis/mapping/ObjectHashMapperTests.java b/src/test/java/org/springframework/data/redis/mapping/ObjectHashMapperTests.java index 146a4409a..1888d8ec6 100644 --- a/src/test/java/org/springframework/data/redis/mapping/ObjectHashMapperTests.java +++ b/src/test/java/org/springframework/data/redis/mapping/ObjectHashMapperTests.java @@ -15,14 +15,15 @@ */ package org.springframework.data.redis.mapping; -import static org.assertj.core.api.Assertions.*; - -import lombok.Data; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import java.util.Collections; import java.util.Map; +import java.util.Objects; import org.junit.jupiter.api.Test; + import org.springframework.data.annotation.TypeAlias; import org.springframework.data.redis.core.convert.MappingRedisConverter; import org.springframework.data.redis.core.mapping.RedisMappingContext; @@ -33,34 +34,36 @@ import org.springframework.data.redis.hash.ObjectHashMapper; * * @author Christoph Strobl * @author Mark Paluch + * @author John Blum */ class ObjectHashMapperTests extends AbstractHashMapperTests { - protected ObjectHashMapper mapperFor(Class t) { + @SuppressWarnings("rawtypes") + protected ObjectHashMapper mapperFor(Class type) { return new ObjectHashMapper(); } @Test // DATAREDIS-503 void testSimpleType() { - assertBackAndForwardMapping(new Integer(100)); + assertBackAndForwardMapping(100); } @Test // DATAREDIS-503 void fromHashShouldCastToType() { ObjectHashMapper objectHashMapper = new ObjectHashMapper(); - Map hash = objectHashMapper.toHash(new Integer(100)); + Map hash = objectHashMapper.toHash(100); Integer result = objectHashMapper.fromHash(hash, Integer.class); - assertThat(result).isEqualTo(new Integer(100)); + assertThat(result).isEqualTo(100); } @Test // DATAREDIS-503 void fromHashShouldFailIfTypeDoesNotMatch() { ObjectHashMapper objectHashMapper = new ObjectHashMapper(); - Map hash = objectHashMapper.toHash(new Integer(100)); + Map hash = objectHashMapper.toHash(100); assertThatExceptionOfType(ClassCastException.class).isThrownBy(() -> objectHashMapper.fromHash(hash, String.class)); } @@ -84,9 +87,35 @@ class ObjectHashMapperTests extends AbstractHashMapperTests { } @TypeAlias("_42_") - @Data static class WithTypeAlias { - String value; - } + private String value; + + public String getValue() { + return this.value; + } + + public void setValue(String value) { + this.value = value; + } + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof WithTypeAlias that)) { + return false; + } + + return Objects.equals(this.getValue(), that.getValue()); + } + + @Override + public int hashCode() { + return Objects.hash(getValue()); + } + } } diff --git a/src/test/java/org/springframework/data/redis/repository/RedisRepositoryIntegrationTestBase.java b/src/test/java/org/springframework/data/redis/repository/RedisRepositoryIntegrationTestBase.java index 8b0255fd5..9f35a9920 100644 --- a/src/test/java/org/springframework/data/redis/repository/RedisRepositoryIntegrationTestBase.java +++ b/src/test/java/org/springframework/data/redis/repository/RedisRepositoryIntegrationTestBase.java @@ -15,15 +15,12 @@ */ package org.springframework.data.redis.repository; -import static org.assertj.core.api.Assertions.*; - -import lombok.Data; -import lombok.Value; -import lombok.With; +import static org.assertj.core.api.Assertions.assertThat; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.Optional; import org.junit.jupiter.api.BeforeEach; @@ -58,6 +55,7 @@ import org.springframework.data.repository.query.QueryByExampleExecutor; * * @author Christoph Strobl * @author Mark Paluch + * @author John Blum */ public abstract class RedisRepositoryIntegrationTestBase { @@ -492,12 +490,12 @@ public abstract class RedisRepositoryIntegrationTestBase { Immutable nested = new Immutable("heisenberg", "White", null); Immutable object = new Immutable(null, "Walter", nested); Immutable saved = immutableObjectRepo.save(object); - Immutable loaded = immutableObjectRepo.findById(saved.id).get(); + assertThat(loaded.nested).isEqualTo(nested); } - public static interface PersonRepository + public interface PersonRepository extends PagingAndSortingRepository, CrudRepository, QueryByExampleExecutor { @@ -553,7 +551,7 @@ public abstract class RedisRepositoryIntegrationTestBase { @Override protected Iterable initialConfiguration() { - return Collections. singleton(new SimpleIndexDefinition("persons", "lastname")); + return Collections.singleton(new SimpleIndexDefinition("persons", "lastname")); } } @@ -571,7 +569,6 @@ public abstract class RedisRepositoryIntegrationTestBase { } @RedisHash("persons") - @Data public static class Person { @Id String id; @@ -584,28 +581,207 @@ public abstract class RedisRepositoryIntegrationTestBase { public Person() {} public Person(String firstname, String lastname) { - this.firstname = firstname; this.lastname = lastname; } + + public String getId() { + return this.id; + } + + public void setId(String id) { + this.id = id; + } + + public String getFirstname() { + return this.firstname; + } + + public void setFirstname(String firstname) { + this.firstname = firstname; + } + + public Boolean getAlive() { + return this.alive; + } + + public void setAlive(Boolean alive) { + this.alive = alive; + } + + public String getLastname() { + return this.lastname; + } + + public void setLastname(String lastname) { + this.lastname = lastname; + } + + public City getCity() { + return this.city; + } + + public void setCity(City city) { + this.city = city; + } + + public City getHometown() { + return this.hometown; + } + + public void setHometown(City hometown) { + this.hometown = hometown; + } + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof Person that)) { + return false; + } + + return Objects.equals(this.getId(), that.getId()) + && Objects.equals(this.getFirstname(), that.getFirstname()) + && Objects.equals(this.getLastname(), that.getLastname()) + && Objects.equals(this.getAlive(), that.getAlive()) + && Objects.equals(this.getCity(), that.getCity()) + && Objects.equals(this.getHometown(), that.getHometown()); + } + + @Override + public int hashCode() { + return Objects.hash(getId(), getFirstname(), getLastname(), getAlive(), getCity(), getHometown()); + } } - @Data static class City { @Id String id; String name; - @GeoIndexed Point location; + + public String getId() { + return this.id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public Point getLocation() { + return this.location; + } + + public void setLocation(Point location) { + this.location = location; + } + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof City that)) { + return false; + } + + return Objects.equals(this.getId(), that.getId()) + && Objects.equals(this.getName(), that.getName()) + && Objects.equals(this.getLocation(), that.getLocation()); + } + + @Override + public int hashCode() { + return Objects.hash(getId(), getName(), getLocation()); + } + + @Override + public String toString() { + + return "City{" + + "id='" + id + '\'' + + ", name='" + name + '\'' + + ", location=" + location + + '}'; + } } - @Value - @With - static class Immutable { + static final class Immutable { - @Id String id; - String name; + private final @Id String id; + private final String name; + private final Immutable nested; - Immutable nested; + public Immutable(String id, String name, Immutable nested) { + this.id = id; + this.name = name; + this.nested = nested; + } + + public String getId() { + return this.id; + } + + public String getName() { + return this.name; + } + + public Immutable getNested() { + return this.nested; + } + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof Immutable that)) { + return false; + } + + return Objects.equals(this.getId(), that.getId()) + && Objects.equals(this.getName(), that.getName()) + && Objects.equals(this.getNested(), that.getNested()); + } + + @Override + public int hashCode() { + return Objects.hash(getId(), getName(), getNested()); + } + + public String toString() { + + return "RedisRepositoryIntegrationTestBase.Immutable(id=" + this.getId() + + ", name=" + this.getName() + + ", nested=" + this.getNested() + ")"; + } + + public Immutable withId(String id) { + return Objects.equals(getId(), id) ? this : new Immutable(id, this.name, this.nested); + } + + public Immutable withName(String name) { + return Objects.equals(getName(), name) ? this : new Immutable(this.id, name, this.nested); + } + + public Immutable withNested(Immutable nested) { + return Objects.equals(getNested(), nested) ? this : new Immutable(this.id, this.name, nested); + } } } diff --git a/src/test/java/org/springframework/data/redis/repository/query/ExampleQueryMapperUnitTests.java b/src/test/java/org/springframework/data/redis/repository/query/ExampleQueryMapperUnitTests.java index 14ce0c25c..38439bef6 100644 --- a/src/test/java/org/springframework/data/redis/repository/query/ExampleQueryMapperUnitTests.java +++ b/src/test/java/org/springframework/data/redis/repository/query/ExampleQueryMapperUnitTests.java @@ -15,14 +15,14 @@ */ package org.springframework.data.redis.repository.query; -import static org.assertj.core.api.Assertions.*; - -import lombok.Data; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Objects; import org.junit.jupiter.api.Test; @@ -42,6 +42,7 @@ import org.springframework.data.redis.repository.query.RedisOperationChain.PathA * * @author Mark Paluch * @author Christoph Strobl + * @author John Blum */ public class ExampleQueryMapperUnitTests { @@ -187,7 +188,6 @@ public class ExampleQueryMapperUnitTests { assertThat(operationChain.getSismember()).contains(new PathAndValue("firstname", "WALTER")); } - @Data static class Person { @Id String id; @@ -204,6 +204,102 @@ public class ExampleQueryMapperUnitTests { @Reference Person relative; Species species; + + public String getId() { + return this.id; + } + + public void setId(String id) { + this.id = id; + } + + public String getFirstname() { + return this.firstname; + } + + public void setFirstname(String firstname) { + this.firstname = firstname; + } + + public String getLastname() { + return this.lastname; + } + + public void setLastname(String lastname) { + this.lastname = lastname; + } + + public List getNicknames() { + return this.nicknames; + } + + public void setNicknames(List nicknames) { + this.nicknames = nicknames; + } + + public Integer getAge() { + return this.age; + } + + public void setAge(Integer age) { + this.age = age; + } + + public Gender getGender() { + return this.gender; + } + + public void setGender(Gender gender) { + this.gender = gender; + } + + public Map getPhysicalAttributes() { + return this.physicalAttributes; + } + + public void setPhysicalAttributes(Map physicalAttributes) { + this.physicalAttributes = physicalAttributes; + } + + public Person getRelative() { + return this.relative; + } + + public void setRelative(Person relative) { + this.relative = relative; + } + + public Species getSpecies() { + return this.species; + } + + public void setSpecies(Species species) { + this.species = species; + } + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof Person that)) { + return false; + } + + return Objects.equals(this.getId(), that.getId()) + && Objects.equals(this.getFirstname(), that.getFirstname()) + && Objects.equals(this.getLastname(), that.getLastname()) + && Objects.equals(this.getAge(), that.getAge()) + && Objects.equals(this.getGender(), that.getGender()) + && Objects.equals(this.getSpecies(), that.getSpecies()); + } + + @Override + public int hashCode() { + return Objects.hash(getId(), getFirstname(), getLastname(), getAge(), getGender(), getSpecies()); + } } enum Gender { @@ -218,7 +314,6 @@ public class ExampleQueryMapperUnitTests { } static class Species { - @Indexed String name; } } diff --git a/src/test/java/org/springframework/data/redis/repository/support/QueryByExampleRedisExecutorIntegrationTests.java b/src/test/java/org/springframework/data/redis/repository/support/QueryByExampleRedisExecutorIntegrationTests.java index fd52b67fc..d8cb08af6 100644 --- a/src/test/java/org/springframework/data/redis/repository/support/QueryByExampleRedisExecutorIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/repository/support/QueryByExampleRedisExecutorIntegrationTests.java @@ -15,14 +15,13 @@ */ package org.springframework.data.redis.repository.support; -import static org.assertj.core.api.Assertions.*; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import java.util.Arrays; import java.util.List; +import java.util.Objects; import java.util.Optional; import java.util.stream.Stream; @@ -56,6 +55,7 @@ import org.springframework.data.repository.query.FluentQuery; * * @author Mark Paluch * @author Christoph Strobl + * @author John Blum */ public class QueryByExampleRedisExecutorIntegrationTests { @@ -313,37 +313,151 @@ public class QueryByExampleRedisExecutorIntegrationTests { } @RedisHash("persons") - @Data static class Person { - @Id String id; - @Indexed String firstname; - String lastname; - City hometown; + private @Id String id; + private @Indexed String firstname; + private String lastname; + private City hometown; - Person() {} + Person() { } Person(String firstname, String lastname) { - this.firstname = firstname; this.lastname = lastname; } + + public String getId() { + return this.id; + } + + public void setId(String id) { + this.id = id; + } + + public String getFirstname() { + return this.firstname; + } + + public void setFirstname(String firstname) { + this.firstname = firstname; + } + + public String getLastname() { + return this.lastname; + } + + public void setLastname(String lastname) { + this.lastname = lastname; + } + + public City getHometown() { + return this.hometown; + } + + public void setHometown(City hometown) { + this.hometown = hometown; + } + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof Person that)) { + return false; + } + + return Objects.equals(this.getId(), that.getId()) + && Objects.equals(this.getFirstname(), that.getFirstname()) + && Objects.equals(this.getLastname(), that.getLastname()) + && Objects.equals(this.getHometown(), that.getHometown()); + } + + @Override + public int hashCode() { + return Objects.hash(getId(), getFirstname(), getLastname(), getHometown()); + } } - @Data - @AllArgsConstructor - @NoArgsConstructor static class City { - @Indexed String name; + + private @Indexed String name; + + public City() { } + + public City(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof City that)) { + return false; + } + + return Objects.equals(this.getName(), that.getName()); + } + + @Override + public int hashCode() { + return Objects.hash(getName()); + } } - @Data static class PersonDto { - String firstname; + + private String firstname; + + public String getFirstname() { + return this.firstname; + } + + public void setFirstname(String firstname) { + this.firstname = firstname; + } + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof Person that)) { + return false; + } + + return Objects.equals(this.getFirstname(), that.getLastname()); + } + + @Override + public int hashCode() { + return Objects.hash(getFirstname()); + } + + @Override + public String toString() { + return getFirstname(); + } } interface PersonProjection { - String getFirstname(); } } diff --git a/src/test/java/org/springframework/data/redis/serializer/GenericJackson2JsonRedisSerializerUnitTests.java b/src/test/java/org/springframework/data/redis/serializer/GenericJackson2JsonRedisSerializerUnitTests.java index f1538eeaa..55830ba5b 100644 --- a/src/test/java/org/springframework/data/redis/serializer/GenericJackson2JsonRedisSerializerUnitTests.java +++ b/src/test/java/org/springframework/data/redis/serializer/GenericJackson2JsonRedisSerializerUnitTests.java @@ -15,29 +15,30 @@ */ package org.springframework.data.redis.serializer; -import static org.assertj.core.api.Assertions.*; -import static org.mockito.Mockito.*; -import static org.springframework.test.util.ReflectionTestUtils.*; -import static org.springframework.util.ObjectUtils.*; - -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; -import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; -import lombok.Data; -import lombok.ToString; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.springframework.test.util.ReflectionTestUtils.getField; +import static org.springframework.util.ObjectUtils.nullSafeEquals; +import static org.springframework.util.ObjectUtils.nullSafeHashCode; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.time.LocalDate; +import java.util.Arrays; import java.util.Map; +import java.util.Objects; import java.util.UUID; import java.util.concurrent.atomic.AtomicReference; import org.junit.jupiter.api.Test; import org.mockito.Mockito; + import org.springframework.beans.BeanUtils; import org.springframework.cache.support.NullValue; +import org.springframework.lang.Nullable; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeInfo.As; @@ -47,15 +48,19 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder; import com.fasterxml.jackson.databind.type.TypeFactory; -import org.springframework.lang.Nullable; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; /** * Unit tests for {@link GenericJackson2JsonRedisSerializer}. * * @author Christoph Strobl * @author Mark Paluch + * @author John Blum */ class GenericJackson2JsonRedisSerializerUnitTests { @@ -436,33 +441,77 @@ class GenericJackson2JsonRedisSerializerUnitTests { this.simpleObject = simpleObject; } - @Override - public int hashCode() { - return nullSafeHashCode(stringValue) + nullSafeHashCode(simpleObject); - } - @Override public boolean equals(@Nullable Object obj) { + if (this == obj) { return true; } - if (obj == null) { + + if (!(obj instanceof ComplexObject that)) { return false; } - if (!(obj instanceof ComplexObject)) { - return false; - } - ComplexObject other = (ComplexObject) obj; - return nullSafeEquals(this.stringValue, other.stringValue) - && nullSafeEquals(this.simpleObject, other.simpleObject); + + return Objects.equals(this.simpleObject, that.simpleObject) + && Objects.equals(this.stringValue, that.stringValue); + } + + @Override + public int hashCode() { + return Objects.hash(this.simpleObject, this.stringValue); } } - @Data static final class FinalObject { + public Long longValue; public int[] myArray; SimpleObject simpleObject; + + public Long getLongValue() { + return this.longValue; + } + + public void setLongValue(Long longValue) { + this.longValue = longValue; + } + + public int[] getMyArray() { + return this.myArray; + } + + public void setMyArray(int[] myArray) { + this.myArray = myArray; + } + + public SimpleObject getSimpleObject() { + return this.simpleObject; + } + + public void setSimpleObject(SimpleObject simpleObject) { + this.simpleObject = simpleObject; + } + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof FinalObject that)) { + return false; + } + + return Objects.equals(this.getLongValue(), that.getLongValue()) + && Arrays.equals(this.getMyArray(), that.getMyArray()) + && Objects.equals(this.getSimpleObject(), that.getSimpleObject()); + } + + @Override + public int hashCode() { + return Objects.hash(getLongValue(), getMyArray(), getSimpleObject()); + } } static class SimpleObject { @@ -497,12 +546,23 @@ class GenericJackson2JsonRedisSerializerUnitTests { } } - @ToString static class User { + @JsonView(Views.Basic.class) public int id; @JsonView(Views.Basic.class) public String name; @JsonView(Views.Detailed.class) public String email; @JsonView(Views.Detailed.class) public String mobile; + + @Override + public String toString() { + + return "User{" + + "id=" + id + + ", name='" + name + '\'' + + ", email='" + email + '\'' + + ", mobile='" + mobile + '\'' + + '}'; + } } static class Views { @@ -512,20 +572,109 @@ class GenericJackson2JsonRedisSerializerUnitTests { interface Detailed {} } - @Data static class CountAndArray { private int count; private int[] available; private Long[] arrayOfPrimitiveWrapper; + + public int getCount() { + return this.count; + } + + public void setCount(int count) { + this.count = count; + } + + public int[] getAvailable() { + return this.available; + } + + public void setAvailable(int[] available) { + this.available = available; + } + + public Long[] getArrayOfPrimitiveWrapper() { + return this.arrayOfPrimitiveWrapper; + } + + public void setArrayOfPrimitiveWrapper(Long[] arrayOfPrimitiveWrapper) { + this.arrayOfPrimitiveWrapper = arrayOfPrimitiveWrapper; + } + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof CountAndArray that)) { + return false; + } + + return Objects.equals(this.getCount(), that.getCount()) + && Objects.equals(this.getAvailable(), that.getAvailable()) + && Objects.equals(this.getArrayOfPrimitiveWrapper(), that.getArrayOfPrimitiveWrapper()); + } + + @Override + public int hashCode() { + return Objects.hash(getCount(), getAvailable(), getArrayOfPrimitiveWrapper()); + } } - @Data static class WithWrapperTypes { AtomicReference primitiveWrapper; AtomicReference primitiveArrayWrapper; AtomicReference simpleObjectWrapper; + + public AtomicReference getPrimitiveWrapper() { + return this.primitiveWrapper; + } + + public void setPrimitiveWrapper(AtomicReference primitiveWrapper) { + this.primitiveWrapper = primitiveWrapper; + } + + public AtomicReference getPrimitiveArrayWrapper() { + return this.primitiveArrayWrapper; + } + + public void setPrimitiveArrayWrapper(AtomicReference primitiveArrayWrapper) { + this.primitiveArrayWrapper = primitiveArrayWrapper; + } + + public AtomicReference getSimpleObjectWrapper() { + return this.simpleObjectWrapper; + } + + public void setSimpleObjectWrapper(AtomicReference simpleObjectWrapper) { + this.simpleObjectWrapper = simpleObjectWrapper; + } + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof WithWrapperTypes that)) { + return false; + } + + return Objects.equals(this.getPrimitiveWrapper(), that.getPrimitiveWrapper()) + && Objects.equals(this.getPrimitiveArrayWrapper(), that.getPrimitiveArrayWrapper()) + && Objects.equals(this.getSimpleObjectWrapper(), that.getSimpleObjectWrapper()); + } + + @Override + public int hashCode() { + return Objects.hash(getPrimitiveWrapper(), getPrimitiveArrayWrapper(), getSimpleObjectWrapper()); + } + } enum EnumType { diff --git a/src/test/java/org/springframework/data/redis/serializer/SimpleRedisSerializerTests.java b/src/test/java/org/springframework/data/redis/serializer/SimpleRedisSerializerTests.java index 79ebe7725..4d73ccc35 100644 --- a/src/test/java/org/springframework/data/redis/serializer/SimpleRedisSerializerTests.java +++ b/src/test/java/org/springframework/data/redis/serializer/SimpleRedisSerializerTests.java @@ -15,11 +15,10 @@ */ package org.springframework.data.redis.serializer; -import static org.assertj.core.api.Assertions.*; - -import lombok.EqualsAndHashCode; +import static org.assertj.core.api.Assertions.assertThat; import java.io.Serializable; +import java.util.Objects; import java.util.UUID; import org.junit.jupiter.api.Test; @@ -33,20 +32,58 @@ import org.springframework.instrument.classloading.ShadowingClassLoader; * @author Jennifer Hickey * @author Mark Paluch * @author Christoph Strobl + * @author John Blum */ class SimpleRedisSerializerTests { - @EqualsAndHashCode private static class A implements Serializable { private Integer value = Integer.valueOf(30); + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof A that)) { + return false; + } + + return Objects.equals(this.value, that.value); + } + + @Override + public int hashCode() { + return Objects.hash(this.value); + } } - @EqualsAndHashCode private static class B implements Serializable { - private String name = getClass().getName(); private A a = new A(); + private String name = getClass().getName(); + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof B that)) { + return false; + } + + return Objects.equals(this.a, that.a) + && Objects.equals(this.name, that.name); + } + + @Override + public int hashCode() { + return Objects.hash(this.a, this.name); + } } private RedisSerializer serializer = new JdkSerializationRedisSerializer(); diff --git a/src/test/java/org/springframework/data/redis/stream/AbstractStreamMessageListenerContainerIntegrationTests.java b/src/test/java/org/springframework/data/redis/stream/AbstractStreamMessageListenerContainerIntegrationTests.java index 6f8fcf8a6..f401e5d2b 100644 --- a/src/test/java/org/springframework/data/redis/stream/AbstractStreamMessageListenerContainerIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/stream/AbstractStreamMessageListenerContainerIntegrationTests.java @@ -15,16 +15,12 @@ */ package org.springframework.data.redis.stream; -import static org.assertj.core.api.Assertions.*; - -import io.lettuce.core.codec.StringCodec; -import io.lettuce.core.output.NestedMultiOutput; -import lombok.AllArgsConstructor; -import lombok.Data; +import static org.assertj.core.api.Assertions.assertThat; import java.time.Duration; import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; @@ -52,11 +48,15 @@ import org.springframework.data.redis.stream.StreamMessageListenerContainer.Stre import org.springframework.data.redis.test.condition.EnabledOnCommand; import org.springframework.util.NumberUtils; +import io.lettuce.core.codec.StringCodec; +import io.lettuce.core.output.NestedMultiOutput; + /** * Integration tests for {@link StreamMessageListenerContainer}. * * @author Mark Paluch * @author Christoph Strobl + * @author John Blum */ @EnabledOnCommand("XREAD") @TestInstance(TestInstance.Lifecycle.PER_CLASS) @@ -408,9 +408,58 @@ abstract class AbstractStreamMessageListenerContainerIntegrationTests { return NumberUtils.parseNumber(value, Integer.class); } - @Data - @AllArgsConstructor static class LoginEvent { - String firstname, lastname; + + String firstName, lastName; + + LoginEvent(String firstName, String lastName) { + this.firstName = firstName; + this.lastName = lastName; + } + + public String getFirstName() { + return this.firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return this.lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof LoginEvent that)) { + return false; + } + + return Objects.equals(this.getFirstName(), that.getFirstName()) + && Objects.equals(this.getLastName(), that.getLastName()); + } + + @Override + public int hashCode() { + return Objects.hash(getFirstName(), getLastName()); + } + + @Override + public String toString() { + + return "LoginEvent{" + + "firstname='" + firstName + '\'' + + ", lastname='" + lastName + '\'' + + '}'; + } } } diff --git a/src/test/java/org/springframework/data/redis/stream/StreamReceiverIntegrationTests.java b/src/test/java/org/springframework/data/redis/stream/StreamReceiverIntegrationTests.java index 4dde67e9e..3352f6de8 100644 --- a/src/test/java/org/springframework/data/redis/stream/StreamReceiverIntegrationTests.java +++ b/src/test/java/org/springframework/data/redis/stream/StreamReceiverIntegrationTests.java @@ -15,19 +15,16 @@ */ package org.springframework.data.redis.stream; -import static org.assertj.core.api.Assertions.*; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.*; - -import lombok.AllArgsConstructor; -import lombok.Data; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import java.nio.ByteBuffer; import java.time.Duration; import java.util.Collections; +import java.util.Objects; import java.util.concurrent.atomic.AtomicReference; import org.junit.jupiter.api.BeforeEach; @@ -54,11 +51,16 @@ import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.data.redis.stream.StreamReceiver.StreamReceiverOptions; import org.springframework.data.redis.test.condition.EnabledOnCommand; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; +import reactor.test.StepVerifier; + /** * Integration tests for {@link StreamReceiver}. * * @author Mark Paluch * @author Eddie McDaniel + * @author John Blum */ @EnabledOnCommand("XREAD") @ExtendWith(LettuceConnectionFactoryExtension.class) @@ -290,9 +292,58 @@ public class StreamReceiverIntegrationTests { assertThat(((ConversionFailedException) ref.get()).getValue()).isInstanceOf(ByteBufferRecord.class); } - @Data - @AllArgsConstructor static class LoginEvent { - String firstname, lastname; + + String firstName, lastName; + + LoginEvent(String firstName, String lastName) { + this.firstName = firstName; + this.lastName = lastName; + } + + public String getFirstName() { + return this.firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return this.lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof LoginEvent that)) { + return false; + } + + return Objects.equals(this.getFirstName(), that.getFirstName()) + && Objects.equals(this.getLastName(), that.getLastName()); + } + + @Override + public int hashCode() { + return Objects.hash(getFirstName(), getLastName()); + } + + @Override + public String toString() { + + return "LoginEvent{" + + "firstname='" + firstName + '\'' + + ", lastname='" + lastName + '\'' + + '}'; + } } }