Skip to content

Commit 398eed8

Browse files
committed
Issue #118: Query Creation Uses Attribute Name instead of Column Name
Regression from Spring v4.5
1 parent 2ccb10b commit 398eed8

14 files changed

+394
-72
lines changed

src/main/java/org/socialsignin/spring/data/dynamodb/repository/query/AbstractDynamoDBQueryCriteria.java

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ protected QueryRequest buildQueryRequest(String tableName, String theIndexName,
8888
queryRequest.setIndexName(theIndexName);
8989

9090
if (isApplicableForGlobalSecondaryIndex()) {
91-
List<String> allowedSortProperties = new ArrayList<String>();
91+
List<String> allowedSortProperties = new ArrayList<>();
9292

9393
for (Entry<String, List<Condition>> singlePropertyCondition : propertyConditions.entrySet()) {
9494
if (entityInformation.getGlobalSecondaryIndexNamesByPropertyName().keySet()
@@ -97,7 +97,7 @@ protected QueryRequest buildQueryRequest(String tableName, String theIndexName,
9797
}
9898
}
9999

100-
HashMap<String, Condition> keyConditions = new HashMap<String, Condition>();
100+
HashMap<String, Condition> keyConditions = new HashMap<>();
101101

102102
if (hashKeyConditions != null && hashKeyConditions.size() > 0) {
103103
for (Condition hashKeyCondition : hashKeyConditions) {
@@ -130,7 +130,7 @@ protected QueryRequest buildQueryRequest(String tableName, String theIndexName,
130130

131131
queryRequest.setKeyConditions(keyConditions);
132132
queryRequest.setSelect(Select.ALL_PROJECTED_ATTRIBUTES);
133-
applySortIfSpecified(queryRequest, new ArrayList<String>(new HashSet<String>(allowedSortProperties)));
133+
applySortIfSpecified(queryRequest, new ArrayList<>(new HashSet<>(allowedSortProperties)));
134134
}
135135
return queryRequest;
136136
}
@@ -223,11 +223,11 @@ protected List<Condition> getHashKeyConditions() {
223223

224224
public AbstractDynamoDBQueryCriteria(DynamoDBEntityInformation<T, ID> dynamoDBEntityInformation, final DynamoDBMapperTableModel<T> tableModel) {
225225
this.clazz = dynamoDBEntityInformation.getJavaType();
226-
this.attributeConditions = new LinkedMultiValueMap<String, Condition>();
227-
this.propertyConditions = new LinkedMultiValueMap<String, Condition>();
226+
this.attributeConditions = new LinkedMultiValueMap<>();
227+
this.propertyConditions = new LinkedMultiValueMap<>();
228228
this.hashKeyPropertyName = dynamoDBEntityInformation.getHashKeyPropertyName();
229229
this.entityInformation = dynamoDBEntityInformation;
230-
this.attributeNamesByPropertyName = new HashMap<String, String>();
230+
this.attributeNamesByPropertyName = new HashMap<>();
231231
// TODO consider adding the DynamoDBMapper table model to DynamoDBEntityInformation instead
232232
this.tableModel = tableModel;
233233
}
@@ -257,10 +257,10 @@ protected String getGlobalSecondaryIndexName() {
257257
if (globalSecondaryIndexName == null && attributeConditions != null && !attributeConditions.isEmpty())
258258
{
259259
// Declare map of index names by attribute name which we will populate below - this will be used to determine which index to use if multiple indexes are applicable
260-
Map<String,String[]> indexNamesByAttributeName = new HashMap<String,String[]>();
260+
Map<String, String[]> indexNamesByAttributeName = new HashMap<>();
261261

262262
// Declare map of attribute lists by index name which we will populate below - this will be used to determine whether we have an exact match index for specified attribute conditions
263-
MultiValueMap<String,String> attributeListsByIndexName = new LinkedMultiValueMap<String,String>();
263+
MultiValueMap<String, String> attributeListsByIndexName = new LinkedMultiValueMap<>();
264264

265265
// Populate the above maps
266266
for (Entry<String, String[]> indexNamesForPropertyNameEntry : entityInformation.getGlobalSecondaryIndexNamesByPropertyName().entrySet())
@@ -275,8 +275,8 @@ protected String getGlobalSecondaryIndexName() {
275275
}
276276

277277
// Declare lists to store matching index names
278-
List<String> exactMatchIndexNames = new ArrayList<String>();
279-
List<String> partialMatchIndexNames = new ArrayList<String>();
278+
List<String> exactMatchIndexNames = new ArrayList<>();
279+
List<String> partialMatchIndexNames = new ArrayList<>();
280280

281281
// Populate matching index name lists - an index is either an exact match ( the index attributes match all the specified criteria exactly)
282282
// or a partial match ( the properties for the specified criteria are contained within the property set for an index )
@@ -412,8 +412,7 @@ public Object getHashKeyPropertyValue() {
412412
protected String getAttributeName(String propertyName) {
413413
String attributeName = attributeNamesByPropertyName.get(propertyName);
414414
if (attributeName == null) {
415-
String overriddenName = entityInformation.getOverriddenAttributeName(propertyName);
416-
attributeName = overriddenName != null ? overriddenName : propertyName;
415+
attributeName = entityInformation.getOverriddenAttributeName(propertyName).orElse(propertyName);
417416
attributeNamesByPropertyName.put(propertyName, attributeName);
418417
}
419418
return attributeName;
@@ -498,7 +497,11 @@ protected <V extends Object> Object getPropertyAttributeValue(final String prope
498497
if (marshaller != null) {
499498
return marshaller.marshall(value);
500499
} else if (tableModel != null) { // purely here for testing as DynamoDBMapperTableModel cannot be mocked using Mockito
501-
DynamoDBMapperFieldModel<T,Object> fieldModel = tableModel.field(propertyName);
500+
501+
String attributeName = getAttributeName(propertyName);
502+
entityInformation.getOverriddenAttributeName(propertyName).orElse(propertyName);
503+
504+
DynamoDBMapperFieldModel<T,Object> fieldModel = tableModel.field(attributeName);
502505
if (fieldModel != null) {
503506
return fieldModel.convert(value);
504507
}
@@ -515,7 +518,7 @@ protected <V> Condition createNoValueCondition(String propertyName, ComparisonOp
515518
}
516519

517520
private List<String> getNumberListAsStringList(List<Number> numberList) {
518-
List<String> list = new ArrayList<String>();
521+
List<String> list = new ArrayList<>();
519522
for (Number number : numberList) {
520523
if (number != null) {
521524
list.add(number.toString());
@@ -541,7 +544,7 @@ private List<String> getDateListAsStringList(List<Date> dateList) {
541544

542545
private List<String> getInstantListAsStringList(List<Instant> dateList) {
543546
DynamoDBMarshaller<Instant> marshaller = new Instant2IsoDynamoDBMarshaller();
544-
List<String> list = new ArrayList<String>();
547+
List<String> list = new ArrayList<>();
545548
for (Instant date : dateList) {
546549
if (date != null) {
547550
list.add(marshaller.marshall(date));
@@ -553,7 +556,7 @@ private List<String> getInstantListAsStringList(List<Instant> dateList) {
553556
}
554557

555558
private List<String> getBooleanListAsStringList(List<Boolean> booleanList) {
556-
List<String> list = new ArrayList<String>();
559+
List<String> list = new ArrayList<>();
557560
for (Boolean booleanValue : booleanList) {
558561
if (booleanValue != null) {
559562
list.add(booleanValue.booleanValue() ? "1" : "0");
@@ -567,9 +570,8 @@ private List<String> getBooleanListAsStringList(List<Boolean> booleanList) {
567570
@SuppressWarnings("unchecked")
568571
private <P> List<P> getAttributeValueAsList(Object attributeValue) {
569572
boolean isIterable = ClassUtils.isAssignable(Iterable.class, attributeValue.getClass());
570-
List<P> attributeValueAsList = null;
571573
if (isIterable) {
572-
attributeValueAsList = new ArrayList<P>();
574+
List<P> attributeValueAsList = new ArrayList<>();
573575
Iterable<P> iterable = (Iterable<P>) attributeValue;
574576
for (P attributeValueElement : iterable) {
575577
attributeValueAsList.add(attributeValueElement);
@@ -643,7 +645,7 @@ protected Condition createSingleValueCondition(String propertyName, ComparisonOp
643645
Assert.notNull(o, "Creating conditions on null property values not supported: please specify a value for '"
644646
+ propertyName + "'");
645647

646-
List<AttributeValue> attributeValueList = new ArrayList<AttributeValue>();
648+
List<AttributeValue> attributeValueList = new ArrayList<>();
647649
Object attributeValue = !alreadyMarshalledIfRequired ? getPropertyAttributeValue(propertyName, o) : o;
648650
if (ClassUtils.isAssignableValue(AttributeValue.class, attributeValue)) {
649651
attributeValueList.add((AttributeValue) attributeValue);

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

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import java.util.HashMap;
3838
import java.util.List;
3939
import java.util.Map;
40+
import java.util.Optional;
4041

4142
/**
4243
* @author Michael Lavelle
@@ -221,64 +222,64 @@ public String getOverriddenAttributeName(Method method) {
221222
}
222223

223224
@Override
224-
public String getOverriddenAttributeName(final String propertyName) {
225+
public Optional<String> getOverriddenAttributeName(final String propertyName) {
225226

226227
Method method = findMethod(propertyName);
227228
if (method != null) {
228229
if (method.getAnnotation(DynamoDBAttribute.class) != null
229230
&& !StringUtils.isEmpty(method.getAnnotation(DynamoDBAttribute.class).attributeName())) {
230-
return method.getAnnotation(DynamoDBAttribute.class).attributeName();
231+
return Optional.of(method.getAnnotation(DynamoDBAttribute.class).attributeName());
231232
}
232233
if (method.getAnnotation(DynamoDBHashKey.class) != null
233234
&& !StringUtils.isEmpty(method.getAnnotation(DynamoDBHashKey.class).attributeName())) {
234-
return method.getAnnotation(DynamoDBHashKey.class).attributeName();
235+
return Optional.of(method.getAnnotation(DynamoDBHashKey.class).attributeName());
235236
}
236237
if (method.getAnnotation(DynamoDBRangeKey.class) != null
237238
&& !StringUtils.isEmpty(method.getAnnotation(DynamoDBRangeKey.class).attributeName())) {
238-
return method.getAnnotation(DynamoDBRangeKey.class).attributeName();
239+
return Optional.of(method.getAnnotation(DynamoDBRangeKey.class).attributeName());
239240
}
240241
if (method.getAnnotation(DynamoDBIndexRangeKey.class) != null
241242
&& !StringUtils.isEmpty(method.getAnnotation(DynamoDBIndexRangeKey.class).attributeName())) {
242-
return method.getAnnotation(DynamoDBIndexRangeKey.class).attributeName();
243+
return Optional.of(method.getAnnotation(DynamoDBIndexRangeKey.class).attributeName());
243244
}
244245
if (method.getAnnotation(DynamoDBIndexHashKey.class) != null
245246
&& !StringUtils.isEmpty(method.getAnnotation(DynamoDBIndexHashKey.class).attributeName())) {
246-
return method.getAnnotation(DynamoDBIndexHashKey.class).attributeName();
247+
return Optional.of(method.getAnnotation(DynamoDBIndexHashKey.class).attributeName());
247248
}
248249
if (method.getAnnotation(DynamoDBVersionAttribute.class) != null
249250
&& !StringUtils.isEmpty(method.getAnnotation(DynamoDBVersionAttribute.class).attributeName())) {
250-
return method.getAnnotation(DynamoDBVersionAttribute.class).attributeName();
251+
return Optional.of(method.getAnnotation(DynamoDBVersionAttribute.class).attributeName());
251252
}
252253
}
253254

254255
Field field = findField(propertyName);
255256
if (field != null) {
256257
if (field.getAnnotation(DynamoDBAttribute.class) != null
257258
&& !StringUtils.isEmpty(field.getAnnotation(DynamoDBAttribute.class).attributeName())) {
258-
return field.getAnnotation(DynamoDBAttribute.class).attributeName();
259+
return Optional.of(field.getAnnotation(DynamoDBAttribute.class).attributeName());
259260
}
260261
if (field.getAnnotation(DynamoDBHashKey.class) != null
261262
&& !StringUtils.isEmpty(field.getAnnotation(DynamoDBHashKey.class).attributeName())) {
262-
return field.getAnnotation(DynamoDBHashKey.class).attributeName();
263+
return Optional.of(field.getAnnotation(DynamoDBHashKey.class).attributeName());
263264
}
264265
if (field.getAnnotation(DynamoDBRangeKey.class) != null
265266
&& !StringUtils.isEmpty(field.getAnnotation(DynamoDBRangeKey.class).attributeName())) {
266-
return field.getAnnotation(DynamoDBRangeKey.class).attributeName();
267+
return Optional.of(field.getAnnotation(DynamoDBRangeKey.class).attributeName());
267268
}
268269
if (field.getAnnotation(DynamoDBIndexRangeKey.class) != null
269270
&& !StringUtils.isEmpty(field.getAnnotation(DynamoDBIndexRangeKey.class).attributeName())) {
270-
return field.getAnnotation(DynamoDBIndexRangeKey.class).attributeName();
271+
return Optional.of(field.getAnnotation(DynamoDBIndexRangeKey.class).attributeName());
271272
}
272273
if (field.getAnnotation(DynamoDBIndexHashKey.class) != null
273274
&& !StringUtils.isEmpty(field.getAnnotation(DynamoDBIndexHashKey.class).attributeName())) {
274-
return field.getAnnotation(DynamoDBIndexHashKey.class).attributeName();
275+
return Optional.of(field.getAnnotation(DynamoDBIndexHashKey.class).attributeName());
275276
}
276277
if (field.getAnnotation(DynamoDBVersionAttribute.class) != null
277278
&& !StringUtils.isEmpty(field.getAnnotation(DynamoDBVersionAttribute.class).attributeName())) {
278-
return field.getAnnotation(DynamoDBVersionAttribute.class).attributeName();
279+
return Optional.of(field.getAnnotation(DynamoDBVersionAttribute.class).attributeName());
279280
}
280281
}
281-
return null;
282+
return Optional.empty();
282283

283284
}
284285

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

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.springframework.data.repository.core.EntityMetadata;
2020

2121
import java.util.Map;
22+
import java.util.Optional;
2223

2324
/**
2425
* Obtains basic hash key-related metadata about a DynamoDBEntity, such as
@@ -30,15 +31,15 @@
3031
*/
3132
public interface DynamoDBHashKeyExtractingEntityMetadata<T> extends EntityMetadata<T> {
3233

33-
public String getOverriddenAttributeName(String propertyName);
34+
Optional<String> getOverriddenAttributeName(String propertyName);
3435

35-
public DynamoDBMarshaller<?> getMarshallerForProperty(String propertyName);
36+
DynamoDBMarshaller<?> getMarshallerForProperty(String propertyName);
3637

37-
public boolean isHashKeyProperty(String propertyName);
38+
boolean isHashKeyProperty(String propertyName);
3839

39-
public String getHashKeyPropertyName();
40+
String getHashKeyPropertyName();
4041

41-
public String getDynamoDBTableName();
42+
String getDynamoDBTableName();
4243

4344
Map<String, String[]> getGlobalSecondaryIndexNamesByPropertyName();
4445

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.springframework.data.repository.core.support.ReflectionEntityInformation;
2121

2222
import java.util.Map;
23+
import java.util.Optional;
2324
import java.util.Set;
2425

2526
/**
@@ -60,7 +61,7 @@ public Object getRangeKey(final ID id) {
6061
}
6162

6263
@Override
63-
public String getOverriddenAttributeName(String attributeName) {
64+
public Optional<String> getOverriddenAttributeName(String attributeName) {
6465
return metadata.getOverriddenAttributeName(attributeName);
6566
}
6667

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.springframework.util.Assert;
2121

2222
import java.util.Map;
23+
import java.util.Optional;
2324

2425
/**
2526
* Encapsulates minimal information needed to load DynamoDB entities.
@@ -65,7 +66,7 @@ public boolean isRangeKeyAware() {
6566
}
6667

6768
@Override
68-
public String getOverriddenAttributeName(String attributeName) {
69+
public Optional<String> getOverriddenAttributeName(String attributeName) {
6970
return metadata.getOverriddenAttributeName(attributeName);
7071
}
7172

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,17 @@ public class DynamoDBRepositoryFactory extends RepositoryFactorySupport {
4343
private static final Logger LOGGER = LoggerFactory.getLogger(DynamoDBRepositoryFactory.class);
4444

4545
static {
46+
final String DEVELOPMENT = "DEVELOPMENT";
47+
4648
String awsSdkVersion = VersionInfoUtils.getVersion();
4749
String springDataVersion = Version.class.getPackage().getImplementationVersion();
4850

4951
String thisSpecVersion = DynamoDBRepositoryFactory.class.getPackage().getSpecificationVersion();
5052
String thisImplVersion = DynamoDBRepositoryFactory.class.getPackage().getImplementationVersion();
53+
if (thisImplVersion == null || thisSpecVersion == null) {
54+
thisSpecVersion = DEVELOPMENT;
55+
thisImplVersion = DEVELOPMENT;
56+
}
5157

5258
LOGGER.info("Spring Data DynamoDB Version: {} ({})", thisImplVersion, thisSpecVersion);
5359
LOGGER.info("Spring Data Version: {}", springDataVersion);
@@ -57,7 +63,7 @@ public class DynamoDBRepositoryFactory extends RepositoryFactorySupport {
5763
LOGGER.info("Platform Details: {} {}", System.getProperty("os.name"),
5864
System.getProperty("os.version"));
5965

60-
if (!isCompatible(springDataVersion, thisSpecVersion)) {
66+
if (!DEVELOPMENT.equals(thisImplVersion) && !isCompatible(springDataVersion, thisSpecVersion)) {
6167
LOGGER.warn("This Spring Data DynamoDB implementation might not be compatible with the available Spring Data classes on the classpath!"
6268
+ System.getProperty("line.separator") + "NoDefClassFoundExceptions or similar might occur!");
6369
}

0 commit comments

Comments
 (0)