Skip to content

Commit 7b00683

Browse files
#42 Upgrading to 1.9.0 of aws-sdk and adding initial support for DynamoDB field annotations
1 parent 51dddd6 commit 7b00683

9 files changed

+244
-20
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
<commons.lang>3.1</commons.lang>
3535
<httpcomponents>4.2.2</httpcomponents>
3636
<springdata.commons>1.8.0.RELEASE</springdata.commons>
37-
<aws-java-sdk>1.7.9</aws-java-sdk>
37+
<aws-java-sdk>1.9.0</aws-java-sdk>
3838
</properties>
3939

4040
<developers>

src/main/java/org/socialsignin/spring/data/dynamodb/mapping/DynamoDBMappingContext.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,13 @@ protected boolean shouldCreatePersistentEntityFor(TypeInformation<?> type) {
8383
if (method.isAnnotationPresent(DynamoDBRangeKey.class))
8484
hasRangeKey = true;
8585

86+
}
87+
for (Field field : type.getType().getFields()) {
88+
if (field.isAnnotationPresent(DynamoDBHashKey.class))
89+
hasHashKey = true;
90+
if (field.isAnnotationPresent(DynamoDBRangeKey.class))
91+
hasRangeKey = true;
92+
8693
}
8794
return type.getType().isAnnotationPresent(DynamoDBTable.class) || (hasHashKey && hasRangeKey);
8895
}

src/main/java/org/socialsignin/spring/data/dynamodb/repository/support/CompositeIdHashAndRangeKeyExtractor.java

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package org.socialsignin.spring.data.dynamodb.repository.support;
1717

1818
import java.io.Serializable;
19+
import java.lang.reflect.Method;
1920

2021
import org.springframework.util.ReflectionUtils;
2122

@@ -33,13 +34,27 @@ public CompositeIdHashAndRangeKeyExtractor(Class<ID> idClass) {
3334
@SuppressWarnings("unchecked")
3435
@Override
3536
public H getHashKey(ID id) {
36-
37-
return (H) ReflectionUtils.invokeMethod(hashAndRangeKeyMethodExtractor.getHashKeyMethod(), id);
37+
Method method = hashAndRangeKeyMethodExtractor.getHashKeyMethod();
38+
if (method != null)
39+
{
40+
return (H) ReflectionUtils.invokeMethod(method, id);
41+
}
42+
else
43+
{
44+
return (H) ReflectionUtils.getField(hashAndRangeKeyMethodExtractor.getHashKeyField(), id);
45+
}
3846
}
3947

4048
@Override
4149
public Object getRangeKey(ID id) {
42-
return ReflectionUtils.invokeMethod(hashAndRangeKeyMethodExtractor.getRangeKeyMethod(), id);
43-
}
50+
Method method = hashAndRangeKeyMethodExtractor.getRangeKeyMethod();
51+
if (method != null)
52+
{
53+
return ReflectionUtils.invokeMethod(method, id);
54+
}
55+
else
56+
{
57+
return ReflectionUtils.getField(hashAndRangeKeyMethodExtractor.getRangeKeyField(), id);
58+
} }
4459

4560
}

src/main/java/org/socialsignin/spring/data/dynamodb/repository/support/DynamoDBEntityMetadataSupport.java

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.apache.commons.lang3.StringUtils;
2828
import org.springframework.util.Assert;
2929
import org.springframework.util.ReflectionUtils;
30+
import org.springframework.util.ReflectionUtils.FieldCallback;
3031
import org.springframework.util.ReflectionUtils.MethodCallback;
3132

3233
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute;
@@ -93,7 +94,26 @@ public void doWith(Method method) {
9394
}
9495
}
9596
});
96-
Assert.notNull(hashKeyPropertyName, "Unable to find hash key getter method on " + domainType + "!");
97+
ReflectionUtils.doWithFields(domainType, new FieldCallback() {
98+
public void doWith(Field field) {
99+
if (field.getAnnotation(DynamoDBHashKey.class) != null) {
100+
hashKeyPropertyName = getPropertyNameForField(field);
101+
}
102+
if (field.getAnnotation(DynamoDBRangeKey.class) != null) {
103+
hasRangeKey = true;
104+
}
105+
DynamoDBIndexRangeKey dynamoDBRangeKeyAnnotation = field.getAnnotation(DynamoDBIndexRangeKey.class);
106+
DynamoDBIndexHashKey dynamoDBHashKeyAnnotation = field.getAnnotation(DynamoDBIndexHashKey.class);
107+
108+
if (dynamoDBRangeKeyAnnotation != null) {
109+
addGlobalSecondaryIndexNames(field, dynamoDBRangeKeyAnnotation);
110+
}
111+
if (dynamoDBHashKeyAnnotation != null) {
112+
addGlobalSecondaryIndexNames(field, dynamoDBHashKeyAnnotation);
113+
}
114+
}
115+
});
116+
Assert.notNull(hashKeyPropertyName, "Unable to find hash key field or getter method on " + domainType + "!");
97117
}
98118

99119
public DynamoDBEntityInformation<T, ID> getEntityInformation() {
@@ -229,6 +249,34 @@ public String getOverriddenAttributeName(final String propertyName) {
229249
return method.getAnnotation(DynamoDBVersionAttribute.class).attributeName();
230250
}
231251
}
252+
253+
Field field = findField(propertyName);
254+
if (field != null) {
255+
if (field.getAnnotation(DynamoDBAttribute.class) != null
256+
&& StringUtils.isNotEmpty(field.getAnnotation(DynamoDBAttribute.class).attributeName())) {
257+
return field.getAnnotation(DynamoDBAttribute.class).attributeName();
258+
}
259+
if (field.getAnnotation(DynamoDBHashKey.class) != null
260+
&& StringUtils.isNotEmpty(field.getAnnotation(DynamoDBHashKey.class).attributeName())) {
261+
return field.getAnnotation(DynamoDBHashKey.class).attributeName();
262+
}
263+
if (field.getAnnotation(DynamoDBRangeKey.class) != null
264+
&& StringUtils.isNotEmpty(field.getAnnotation(DynamoDBRangeKey.class).attributeName())) {
265+
return field.getAnnotation(DynamoDBRangeKey.class).attributeName();
266+
}
267+
if (field.getAnnotation(DynamoDBIndexRangeKey.class) != null
268+
&& StringUtils.isNotEmpty(field.getAnnotation(DynamoDBIndexRangeKey.class).attributeName())) {
269+
return field.getAnnotation(DynamoDBIndexRangeKey.class).attributeName();
270+
}
271+
if (field.getAnnotation(DynamoDBIndexHashKey.class) != null
272+
&& StringUtils.isNotEmpty(field.getAnnotation(DynamoDBIndexHashKey.class).attributeName())) {
273+
return field.getAnnotation(DynamoDBIndexHashKey.class).attributeName();
274+
}
275+
if (field.getAnnotation(DynamoDBVersionAttribute.class) != null
276+
&& StringUtils.isNotEmpty(field.getAnnotation(DynamoDBVersionAttribute.class).attributeName())) {
277+
return field.getAnnotation(DynamoDBVersionAttribute.class).attributeName();
278+
}
279+
}
232280
return null;
233281

234282
}
@@ -265,6 +313,10 @@ protected String getPropertyNameForAccessorMethod(Method method) {
265313
String remainder = propertyName.substring(1);
266314
return firstLetter.toLowerCase() + remainder;
267315
}
316+
317+
protected String getPropertyNameForField(Field field) {
318+
return field.getName();
319+
}
268320

269321
@Override
270322
public String getHashKeyPropertyName() {
@@ -293,6 +345,28 @@ private void addGlobalSecondaryIndexNames(Method method, DynamoDBIndexRangeKey d
293345

294346
}
295347

348+
private void addGlobalSecondaryIndexNames(Field field, DynamoDBIndexRangeKey dynamoDBIndexRangeKey) {
349+
350+
if (dynamoDBIndexRangeKey.globalSecondaryIndexNames() != null
351+
&& dynamoDBIndexRangeKey.globalSecondaryIndexNames().length > 0) {
352+
String propertyName = getPropertyNameForField(field);
353+
354+
globalSecondaryIndexNames.put(propertyName, field.getAnnotation(DynamoDBIndexRangeKey.class)
355+
.globalSecondaryIndexNames());
356+
globalIndexRangeKeyPropertyNames.add(propertyName);
357+
358+
}
359+
if (dynamoDBIndexRangeKey.globalSecondaryIndexName() != null
360+
&& dynamoDBIndexRangeKey.globalSecondaryIndexName().trim().length() > 0) {
361+
String propertyName = getPropertyNameForField(field);
362+
globalSecondaryIndexNames.put(propertyName,
363+
new String[] { field.getAnnotation(DynamoDBIndexRangeKey.class).globalSecondaryIndexName() });
364+
globalIndexRangeKeyPropertyNames.add(propertyName);
365+
366+
}
367+
368+
}
369+
296370
private void addGlobalSecondaryIndexNames(Method method, DynamoDBIndexHashKey dynamoDBIndexHashKey) {
297371

298372
if (dynamoDBIndexHashKey.globalSecondaryIndexNames() != null
@@ -314,6 +388,28 @@ private void addGlobalSecondaryIndexNames(Method method, DynamoDBIndexHashKey dy
314388

315389
}
316390
}
391+
392+
private void addGlobalSecondaryIndexNames(Field field, DynamoDBIndexHashKey dynamoDBIndexHashKey) {
393+
394+
if (dynamoDBIndexHashKey.globalSecondaryIndexNames() != null
395+
&& dynamoDBIndexHashKey.globalSecondaryIndexNames().length > 0) {
396+
String propertyName = getPropertyNameForField(field);
397+
398+
globalSecondaryIndexNames.put(propertyName, field.getAnnotation(DynamoDBIndexHashKey.class)
399+
.globalSecondaryIndexNames());
400+
globalIndexHashKeyPropertyNames.add(propertyName);
401+
402+
}
403+
if (dynamoDBIndexHashKey.globalSecondaryIndexName() != null
404+
&& dynamoDBIndexHashKey.globalSecondaryIndexName().trim().length() > 0) {
405+
String propertyName = getPropertyNameForField(field);
406+
407+
globalSecondaryIndexNames.put(propertyName,
408+
new String[] { field.getAnnotation(DynamoDBIndexHashKey.class).globalSecondaryIndexName() });
409+
globalIndexHashKeyPropertyNames.add(propertyName);
410+
411+
}
412+
}
317413

318414
@Override
319415
public Map<String, String[]> getGlobalSecondaryIndexNamesByPropertyName() {

src/main/java/org/socialsignin/spring/data/dynamodb/repository/support/DynamoDBHashAndRangeKeyExtractingEntityMetadataImpl.java

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,15 @@
1616
package org.socialsignin.spring.data.dynamodb.repository.support;
1717

1818
import java.io.Serializable;
19+
import java.lang.reflect.Field;
1920
import java.lang.reflect.Method;
2021
import java.util.HashSet;
2122
import java.util.Set;
2223

2324
import org.springframework.data.annotation.Id;
2425
import org.springframework.util.Assert;
2526
import org.springframework.util.ReflectionUtils;
27+
import org.springframework.util.ReflectionUtils.FieldCallback;
2628
import org.springframework.util.ReflectionUtils.MethodCallback;
2729

2830
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey;
@@ -37,6 +39,7 @@ public class DynamoDBHashAndRangeKeyExtractingEntityMetadataImpl<T, ID extends S
3739
private DynamoDBHashAndRangeKeyMethodExtractor<T> hashAndRangeKeyMethodExtractor;
3840

3941
private Method hashKeySetterMethod;
42+
private Field hashKeyField;
4043

4144
public DynamoDBHashAndRangeKeyExtractingEntityMetadataImpl(final Class<T> domainType) {
4245
super(domainType);
@@ -51,7 +54,18 @@ public void doWith(Method method) {
5154
}
5255
}
5356
});
54-
Assert.notNull(hashKeySetterMethod, "Unable to find hash key setter method on " + domainType + "!");
57+
ReflectionUtils.doWithFields(domainType, new FieldCallback() {
58+
public void doWith(Field field) {
59+
if (field.getAnnotation(DynamoDBHashKey.class) != null) {
60+
61+
hashKeyField = ReflectionUtils.findField(domainType, field.getName());
62+
63+
}
64+
}
65+
});
66+
Assert.isTrue(hashKeySetterMethod != null || hashKeyField != null, "Unable to find hash key field or setter method on " + domainType + "!");
67+
Assert.isTrue(hashKeySetterMethod == null || hashKeyField == null, "Found both hash key field and setter method on " + domainType + "!");
68+
5569
}
5670

5771
@Override
@@ -79,14 +93,33 @@ public void doWith(Method method) {
7993
}
8094
}
8195
});
96+
ReflectionUtils.doWithFields(getJavaType(), new FieldCallback() {
97+
public void doWith(Field field) {
98+
if (field.getAnnotation(DynamoDBIndexRangeKey.class) != null) {
99+
if ((field.getAnnotation(DynamoDBIndexRangeKey.class).localSecondaryIndexName() != null && field
100+
.getAnnotation(DynamoDBIndexRangeKey.class).localSecondaryIndexName().trim().length() > 0)
101+
|| (field.getAnnotation(DynamoDBIndexRangeKey.class).localSecondaryIndexNames() != null && field
102+
.getAnnotation(DynamoDBIndexRangeKey.class).localSecondaryIndexNames().length > 0)) {
103+
propertyNames.add(getPropertyNameForField(field));
104+
}
105+
}
106+
}
107+
});
82108
return propertyNames;
83109
}
84110

85111
public T getHashKeyPropotypeEntityForHashKey(Object hashKey) {
86112

87113
try {
88114
T entity = getJavaType().newInstance();
89-
ReflectionUtils.invokeMethod(hashKeySetterMethod, entity, hashKey);
115+
if (hashKeySetterMethod != null)
116+
{
117+
ReflectionUtils.invokeMethod(hashKeySetterMethod, entity, hashKey);
118+
}
119+
else
120+
{
121+
ReflectionUtils.setField(hashKeyField, entity, hashKey);
122+
}
90123

91124
return entity;
92125
} catch (InstantiationException e) {
@@ -95,6 +128,8 @@ public T getHashKeyPropotypeEntityForHashKey(Object hashKey) {
95128
throw new RuntimeException(e);
96129
}
97130
}
131+
132+
98133

99134
@Override
100135
public boolean isCompositeHashAndRangeKeyProperty(String propertyName) {

src/main/java/org/socialsignin/spring/data/dynamodb/repository/support/DynamoDBHashAndRangeKeyMethodExtractor.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.socialsignin.spring.data.dynamodb.repository.support;
1717

18+
import java.lang.reflect.Field;
1819
import java.lang.reflect.Method;
1920

2021
import org.springframework.data.repository.core.EntityMetadata;
@@ -27,5 +28,9 @@ public interface DynamoDBHashAndRangeKeyMethodExtractor<ID> extends EntityMetada
2728
Method getHashKeyMethod();
2829

2930
Method getRangeKeyMethod();
31+
32+
Field getHashKeyField();
33+
34+
Field getRangeKeyField();
3035

3136
}

src/main/java/org/socialsignin/spring/data/dynamodb/repository/support/DynamoDBHashAndRangeKeyMethodExtractorImpl.java

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@
1515
*/
1616
package org.socialsignin.spring.data.dynamodb.repository.support;
1717

18+
import java.lang.reflect.Field;
1819
import java.lang.reflect.Method;
1920

2021
import org.springframework.util.Assert;
2122
import org.springframework.util.ReflectionUtils;
23+
import org.springframework.util.ReflectionUtils.FieldCallback;
2224
import org.springframework.util.ReflectionUtils.MethodCallback;
2325

2426
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey;
@@ -33,6 +35,9 @@ public class DynamoDBHashAndRangeKeyMethodExtractorImpl<T> implements DynamoDBHa
3335
private Method hashKeyMethod;
3436
private Method rangeKeyMethod;
3537

38+
private Field hashKeyField;
39+
private Field rangeKeyField;
40+
3641
/**
3742
* Creates a new {@link DefaultJpaEntityMetadata} for the given domain type.
3843
*
@@ -53,6 +58,17 @@ public void doWith(Method method) {
5358
}
5459
}
5560
});
61+
ReflectionUtils.doWithFields(idType, new FieldCallback() {
62+
public void doWith(Field field) {
63+
if (field.getAnnotation(DynamoDBHashKey.class) != null) {
64+
Assert.isNull(field, "Multiple fields annotated by @DynamoDBHashKey within type " + idType.getName()
65+
+ "!");
66+
ReflectionUtils.makeAccessible(field);
67+
68+
hashKeyField = field;
69+
}
70+
}
71+
});
5672
ReflectionUtils.doWithMethods(idType, new MethodCallback() {
5773
public void doWith(Method method) {
5874
if (method.getAnnotation(DynamoDBRangeKey.class) != null) {
@@ -63,8 +79,20 @@ public void doWith(Method method) {
6379
}
6480
}
6581
});
66-
Assert.notNull(hashKeyMethod, "No method annotated by @DynamoDBHashKey within type " + idType.getName() + "!");
67-
Assert.notNull(rangeKeyMethod, "No method annotated by @DynamoDBRangeKey within type " + idType.getName() + "!");
82+
ReflectionUtils.doWithFields(idType, new FieldCallback() {
83+
public void doWith(Field field) {
84+
if (field.getAnnotation(DynamoDBRangeKey.class) != null) {
85+
Assert.isNull(rangeKeyMethod,
86+
"Multiple methods annotated by @DynamoDBRangeKey within type " + idType.getName() + "!");
87+
ReflectionUtils.makeAccessible(field);
88+
rangeKeyField = field;
89+
}
90+
}
91+
});
92+
Assert.isTrue(hashKeyMethod != null || hashKeyField != null, "No method or field annotated by @DynamoDBHashKey within type " + idType.getName() + "!");
93+
Assert.isTrue(rangeKeyMethod != null || hashKeyField != null, "No method or field annotated by @DynamoDBRangeKey within type " + idType.getName() + "!");
94+
Assert.isTrue(hashKeyMethod == null || hashKeyField == null, "Both method and field annotated by @DynamoDBHashKey within type " + idType.getName() + "!");
95+
Assert.isTrue(rangeKeyMethod == null || hashKeyField == null, "Both method and field annotated by @DynamoDBRangeKey within type " + idType.getName() + "!");
6896

6997
}
7098

@@ -83,5 +111,16 @@ public Method getHashKeyMethod() {
83111
public Method getRangeKeyMethod() {
84112
return rangeKeyMethod;
85113
}
114+
115+
@Override
116+
public Field getHashKeyField() {
117+
118+
return hashKeyField;
119+
}
120+
121+
@Override
122+
public Field getRangeKeyField() {
123+
return rangeKeyField;
124+
}
86125

87126
}

src/main/java/org/socialsignin/spring/data/dynamodb/repository/support/DynamoDBIdIsHashKeyEntityInformationImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
* @author Michael Lavelle
4141
*/
4242
public class DynamoDBIdIsHashKeyEntityInformationImpl<T, ID extends Serializable> extends
43-
GetterReflectionEntityInformation<T, ID> implements DynamoDBEntityInformation<T, ID> {
43+
FieldAndGetterReflectionEntityInformation<T, ID> implements DynamoDBEntityInformation<T, ID> {
4444

4545
private DynamoDBHashKeyExtractingEntityMetadata<T> metadata;
4646
private HashKeyExtractor<ID, ID> hashKeyExtractor;

0 commit comments

Comments
 (0)