2
votes

I have a class mapped to a DynamoDB table, using DynamoDbMapper to query it, and am having the following issue:

When I query by the primary hash key, I get all the values back correctly, but when I query by either of the Global Secondary Index attributes, I still get the object back, and the correct records are always there, but the only fields that are populated are the primary hash key field, and the GSI fields. All others are always null when I query by GSI.

Here is my class:

@DynamoDBTable(tableName="MyTableName")
public class MyClass {

    private String id;
    private String gsiField;
    private String plainField;

    @DynamoDBHashKey(attributeName="Id")
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }

    @DynamoDBIndexHashKey(attributeName="GsiField", globalSecondaryIndexName = "GsiFieldIndex")
    public String getGsiField() {
        return gsiField;
    }
    public void setGsiField(String gsiField) {
        this.gsiField = gsiField;
    }

    @DynamoDBAttribute(attributeName = "PlainField")
    public String getPlainField() {
        return plainField;
    }
    public void setPlainField(String plainField) {
        this.plainField = plainField;
    }
}

And here is the query that searches by GsiField:

public List<MyClass> getListForGsiField(String gsiFieldValue){
    List<MyClass> itemList = null;

    try{
        MyClass partitionKey = new MyClass();
        partitionKey.setGsiField(gsiFieldValue);
        DynamoDBQueryExpression<MyClass> queryExpression = new DynamoDBQueryExpression<>();
        queryExpression.setHashKeyValues(partitionKey);
        queryExpression.setIndexName("GsiFieldIndex");
        queryExpression.setConsistentRead(false);

        itemList = mapper.query(MyClass.class, queryExpression);
    } catch (Exception e){
        log.error(String.format("Exception querying datasource for gsiField %s", gsiFieldValue), e);
        throw e;
    }

    return itemList;
}

Regardless of the value of plainfield in the DynamoDB, my results always look like this:

{
    "Id": "123451234512345",
    "GsiField": "<gsiFieldValue>",
    "PlainField": null
}

Instead of like this:

{
    "Id": "123451234512345",
    "GsiField": "<gsiFieldValue>",
    "PlainField": "<the_value_in_the_database>
}

I'm concerned that I must be performing the query incorrectly, but it matches up with all the successful examples I've found, and does return the correct records as results.

1

1 Answers

4
votes

I guess that the GSI has been created with ProjectionType as KEYS_ONLY.

1) Use the below AWS CLI describe command to check the definition of the table i.e. specifically the GSI definition

aws dynamodb describe-table --table-name MyTableName 

2) Check the Projection on GSI whether it is defined as KEYS_ONLY

 "GlobalSecondaryIndexes": [
     {
         "IndexSizeBytes": 30,
         "IndexName": "indexName",
         "Projection": {
             "ProjectionType": "KEYS_ONLY"
         },

If it is defined as "KEYS_ONLY", then GSI has only Key attributes. You may need to query the main table to get the other attributes (or) you may need to recreate the GSI to project all attributes.