Skip to content

Commit 0856b47

Browse files
committed
Fix toString, equals and hashCode on accessor proxies (JAVA-495).
1 parent 3ad91cc commit 0856b47

4 files changed

Lines changed: 76 additions & 2 deletions

File tree

driver-core/CHANGELOG.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ CHANGELOG
66

77
- [bug] Ignore static fields in mapper (JAVA-510)
88
- [bug] Fix UDT parsing at init when using the default protocol version (JAVA-509)
9+
- [bug] Fix toString, equals and hashCode on accessor proxies (JAVA-495)
910

1011
Merged from 2.0 branch:
1112

driver-mapping/pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@
4848
<scope>test</scope>
4949
</dependency>
5050

51+
<dependency>
52+
<groupId>org.assertj</groupId>
53+
<artifactId>assertj-core</artifactId>
54+
<version>1.7.0</version>
55+
<scope>test</scope>
56+
</dependency>
57+
5158
<dependency>
5259
<groupId>org.ow2.asm</groupId>
5360
<artifactId>asm-all</artifactId>

driver-mapping/src/main/java/com/datastax/driver/mapping/AccessorInvocationHandler.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,19 @@ class AccessorInvocationHandler<T> implements InvocationHandler {
2323

2424
private static final Object[] NO_ARGS = new Object[0];
2525

26+
private static final Method TO_STRING;
27+
private static final Method EQUALS;
28+
private static final Method HASH_CODE;
29+
static {
30+
try {
31+
TO_STRING = Object.class.getMethod("toString");
32+
EQUALS = Object.class.getMethod("equals", Object.class);
33+
HASH_CODE = Object.class.getMethod("hashCode");
34+
} catch (NoSuchMethodException e) {
35+
throw new AssertionError(e); // Can't happen
36+
}
37+
}
38+
2639
private final AccessorMapper<T> mapper;
2740

2841
private final Map<Method, MethodMapper> methodMap = new HashMap<Method, MethodMapper>();
@@ -35,11 +48,20 @@ class AccessorInvocationHandler<T> implements InvocationHandler {
3548
}
3649

3750
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
51+
if (m.equals(TO_STRING))
52+
return mapper.daoClass.getSimpleName() + " implementation generated by the Cassandra driver mapper";
53+
54+
// It's unlikely that equals and hashCode will be used on accessor implementations, but better safe than sorry.
55+
// Identity equality is enough, given that the mapper always returns the same instance for a given accessor.
56+
if (m.equals(EQUALS))
57+
return proxy == args[0];
58+
59+
if (m.equals(HASH_CODE))
60+
return System.identityHashCode(proxy);
3861

3962
MethodMapper method = methodMap.get(m);
40-
if (mapper == null)
63+
if (method == null)
4164
throw new UnsupportedOperationException();
42-
4365
return method.invoke(args == null ? NO_ARGS : args);
4466
}
4567
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.datastax.driver.mapping;
2+
3+
import java.util.Collection;
4+
5+
import com.google.common.collect.Lists;
6+
import org.testng.annotations.Test;
7+
8+
import static org.assertj.core.api.Assertions.assertThat;
9+
10+
import com.datastax.driver.core.CCMBridge;
11+
import com.datastax.driver.core.ResultSet;
12+
import com.datastax.driver.mapping.annotations.Accessor;
13+
import com.datastax.driver.mapping.annotations.Query;
14+
15+
public class MapperAccessorTest extends CCMBridge.PerClassSingleNodeCluster {
16+
17+
@Override protected Collection<String> getTableDefinitions() {
18+
return Lists.newArrayList("CREATE TABLE foo (i int primary key)");
19+
}
20+
21+
@Test(groups = "short")
22+
public void should_implement_toString() {
23+
SystemAccessor accessor = new MappingManager(session)
24+
.createAccessor(SystemAccessor.class);
25+
26+
assertThat(accessor.toString())
27+
.isEqualTo("SystemAccessor implementation generated by the Cassandra driver mapper");
28+
}
29+
30+
@Test(groups = "short")
31+
public void should_implement_equals_and_hashCode() {
32+
SystemAccessor accessor = new MappingManager(session)
33+
.createAccessor(SystemAccessor.class);
34+
35+
assertThat(accessor).isNotEqualTo(new Object());
36+
assertThat(accessor.hashCode()).isEqualTo(System.identityHashCode(accessor));
37+
}
38+
39+
@Accessor
40+
public interface SystemAccessor {
41+
@Query("select release_version from system.local")
42+
ResultSet getCassandraVersion();
43+
}
44+
}

0 commit comments

Comments
 (0)