From 6d8f3a0a20fe3f0f75dc98eccd7080248238f567 Mon Sep 17 00:00:00 2001 From: Craig Andrews Date: Mon, 3 Mar 2014 17:53:21 -0500 Subject: [PATCH] Fix SimpleKey equality with array argument Prior to this commit, an array argument was not handled properly in SimpleKey#equals and SimpleKey#hashCode. As a result, two method invocations with the same array argument lead to two different keys and therefore two different entries in the cache. This commit uses deepEquals and deepHashCode to properly handle methods that have arguments that are array types. Issue: SPR-11505 --- .../cache/interceptor/SimpleKey.java | 5 +- .../interceptor/SimpleKeyGeneratorTests.java | 56 ++++++++++++------- 2 files changed, 39 insertions(+), 22 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/cache/interceptor/SimpleKey.java b/spring-context/src/main/java/org/springframework/cache/interceptor/SimpleKey.java index 80602321cb..097be2d20b 100644 --- a/spring-context/src/main/java/org/springframework/cache/interceptor/SimpleKey.java +++ b/spring-context/src/main/java/org/springframework/cache/interceptor/SimpleKey.java @@ -50,12 +50,13 @@ public final class SimpleKey implements Serializable { @Override public boolean equals(Object obj) { - return (this == obj || (obj instanceof SimpleKey && Arrays.equals(this.params, ((SimpleKey) obj).params))); + return (this == obj || (obj instanceof SimpleKey + && Arrays.deepEquals(this.params, ((SimpleKey) obj).params))); } @Override public int hashCode() { - return Arrays.hashCode(this.params); + return Arrays.deepHashCode(this.params); } @Override diff --git a/spring-context/src/test/java/org/springframework/cache/interceptor/SimpleKeyGeneratorTests.java b/spring-context/src/test/java/org/springframework/cache/interceptor/SimpleKeyGeneratorTests.java index 2d5305dd61..9bd3982f3f 100644 --- a/spring-context/src/test/java/org/springframework/cache/interceptor/SimpleKeyGeneratorTests.java +++ b/spring-context/src/test/java/org/springframework/cache/interceptor/SimpleKeyGeneratorTests.java @@ -25,16 +25,17 @@ import static org.junit.Assert.*; * Tests for {@link SimpleKeyGenerator} and {@link SimpleKey}. * * @author Phillip Webb + * @author Stephane Nicoll */ public class SimpleKeyGeneratorTests { private SimpleKeyGenerator generator = new SimpleKeyGenerator(); @Test - public void noValues() throws Exception { - Object k1 = generator.generate(null, null, new Object[] {}); - Object k2 = generator.generate(null, null, new Object[] {}); - Object k3 = generator.generate(null, null, new Object[] { "different" }); + public void noValues() { + Object k1 = generateKey(new Object[] {}); + Object k2 = generateKey(new Object[] {}); + Object k3 = generateKey(new Object[] { "different" }); assertThat(k1.hashCode(), equalTo(k2.hashCode())); assertThat(k1.hashCode(), not(equalTo(k3.hashCode()))); assertThat(k1, equalTo(k2)); @@ -42,10 +43,10 @@ public class SimpleKeyGeneratorTests { } @Test - public void singleValue() throws Exception { - Object k1 = generator.generate(null, null, new Object[] { "a" }); - Object k2 = generator.generate(null, null, new Object[] { "a" }); - Object k3 = generator.generate(null, null, new Object[] { "different" }); + public void singleValue(){ + Object k1 = generateKey(new Object[] { "a" }); + Object k2 = generateKey(new Object[] { "a" }); + Object k3 = generateKey(new Object[] { "different" }); assertThat(k1.hashCode(), equalTo(k2.hashCode())); assertThat(k1.hashCode(), not(equalTo(k3.hashCode()))); assertThat(k1, equalTo(k2)); @@ -54,10 +55,10 @@ public class SimpleKeyGeneratorTests { } @Test - public void multipleValues() throws Exception { - Object k1 = generator.generate(null, null, new Object[] { "a", 1, "b" }); - Object k2 = generator.generate(null, null, new Object[] { "a", 1, "b" }); - Object k3 = generator.generate(null, null, new Object[] { "b", 1, "a" }); + public void multipleValues() { + Object k1 = generateKey(new Object[] { "a", 1, "b" }); + Object k2 = generateKey(new Object[] { "a", 1, "b" }); + Object k3 = generateKey(new Object[] { "b", 1, "a" }); assertThat(k1.hashCode(), equalTo(k2.hashCode())); assertThat(k1.hashCode(), not(equalTo(k3.hashCode()))); assertThat(k1, equalTo(k2)); @@ -65,10 +66,10 @@ public class SimpleKeyGeneratorTests { } @Test - public void singleNullValue() throws Exception { - Object k1 = generator.generate(null, null, new Object[] { null }); - Object k2 = generator.generate(null, null, new Object[] { null }); - Object k3 = generator.generate(null, null, new Object[] { "different" }); + public void singleNullValue() { + Object k1 = generateKey(new Object[] { null }); + Object k2 = generateKey(new Object[] { null }); + Object k3 = generateKey(new Object[] { "different" }); assertThat(k1.hashCode(), equalTo(k2.hashCode())); assertThat(k1.hashCode(), not(equalTo(k3.hashCode()))); assertThat(k1, equalTo(k2)); @@ -77,13 +78,28 @@ public class SimpleKeyGeneratorTests { } @Test - public void multiplNullValues() throws Exception { - Object k1 = generator.generate(null, null, new Object[] { "a", null, "b", null }); - Object k2 = generator.generate(null, null, new Object[] { "a", null, "b", null }); - Object k3 = generator.generate(null, null, new Object[] { "a", null, "b" }); + public void multipleNullValues() { + Object k1 = generateKey(new Object[] { "a", null, "b", null }); + Object k2 = generateKey(new Object[] { "a", null, "b", null }); + Object k3 = generateKey(new Object[] { "a", null, "b" }); assertThat(k1.hashCode(), equalTo(k2.hashCode())); assertThat(k1.hashCode(), not(equalTo(k3.hashCode()))); assertThat(k1, equalTo(k2)); assertThat(k1, not(equalTo(k3))); } + + @Test + public void arrays() { + Object k1 = generateKey(new Object[] { new String[]{"a", "b"}, "c" }); + Object k2 = generateKey(new Object[] { new String[]{"a", "b"}, "c" }); + Object k3 = generateKey(new Object[] { new String[]{"b", "a"}, "c" }); + assertThat(k1.hashCode(), equalTo(k2.hashCode())); + assertThat(k1.hashCode(), not(equalTo(k3.hashCode()))); + assertThat(k1, equalTo(k2)); + assertThat(k1, not(equalTo(k3))); + } + + private Object generateKey(Object[] arguments) { + return generator.generate(null, null, arguments); + } }