dynamoDb The provided key element does not match the schema error

233 Views Asked by At

I have a dynamoDb table with only hashKey. I am trying to insert a record by using dynamoDbMapper.save method. Although there is no mismatch in key, I am receiving following error.

The provided key element does not match the schema (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException

Table has only hashKey (id) and no sort key. Also there is global secondary index.

My dynamoDb data class is :

 public class DynamoDbData {

    @DynamoDBHashKey(attributeName = "id")
    private String id;

    @DynamoDBIndexRangeKey(globalSecondaryIndexName = "my-index", attributeName = "myfield")
    private String myField;

    @DynamoDBAttribute(attributeName = "title")
    @DynamoDBIndexHashKey(globalSecondaryIndexName = "my-index", attributeName = "title")
    private String title;

 }

and I am trying to save the object by using dynamoDbMapper.

 dynamoDBMapper.save(dynamoDbData);

Usually error says there is a mistmatch in key. But here I have only hashKey in dynamoDb and object which I am trying to save has also only hasKey with same attribute name. What is wrong here? Why am I getting this error ?

Do I need to use seperate objects which has only hashKey or only index?

Note: I can successfully save in tests by using DynamoDBLocal

Output of describe-table:

  {
  "Table": {
    "AttributeDefinitions": [
      {
        "AttributeName": "id",
        "AttributeType": "S"
      },
      {
        "AttributeName": "myfield",
        "AttributeType": "S"
      },
      {
        "AttributeName": "title",
        "AttributeType": "S"
      }
    ],
    "TableName": "myTable",
    "KeySchema": [
      {
        "AttributeName": "id",
        "KeyType": "HASH"
      }
    ],
    "TableStatus": "ACTIVE",
    "CreationDateTime": "2022-11-15T14:44:24.068000+01:00",
    "ProvisionedThroughput": {
      "NumberOfDecreasesToday": 0,
      "ReadCapacityUnits": 0,
      "WriteCapacityUnits": 0
    },
    "TableSizeBytes": 8413,
  
    "GlobalSecondaryIndexes": [
      {
        "IndexName": "my-index",
        "KeySchema": [
          {
            "AttributeName": "title",
            "KeyType": "HASH"
          },
          {
            "AttributeName": "myfield",
            "KeyType": "RANGE"
          }
        ],
        "Projection": {
          "ProjectionType": "KEYS_ONLY"
        },
        "IndexStatus": "ACTIVE",
        "ProvisionedThroughput": {
          "NumberOfDecreasesToday": 0,
          "ReadCapacityUnits": 0,
          "WriteCapacityUnits": 0
        }
      }
    ]
  }
}

Bean definition for mapper :

    @Bean
DynamoDBMapper dynamoDbMapper(AmazonDynamoDB amazonDynamoDB) {
    DynamoDBMapperConfig config = DynamoDBMapperConfig.builder()
            .withPaginationLoadingStrategy(DynamoDBMapperConfig.PaginationLoadingStrategy.EAGER_LOADING)
            .withConsistentReads(DynamoDBMapperConfig.ConsistentReads.CONSISTENT)
            .withTableNameOverride(DynamoDBMapperConfig.TableNameOverride.withTableNamePrefix(properties.getTablePrefix()))
            .build();

    return new DynamoDBMapper(amazonDynamoDB, config);
}
1

There are 1 best solutions below

10
On

This is down to the fact of how Java and DynamoDB infer their variables/attribute names... I've noticed this while using Lombok annotations for the Getter/Setter

Although you have set your hash key annotation to @DynamoDBHashKey(attributeName = "id"), when using the Mapper it will see id as Id, which means it is not matching your key element.

If you are using Lombok then try use a lower case for id:

    @Data
    @DynamoDBTable(tableName = "Stack01")
    public static class DynamoDbData {

        @DynamoDBHashKey(attributeName = "id")
        private String id;

        @DynamoDBAttribute(attributeName = "title")
        @DynamoDBIndexHashKey(globalSecondaryIndexName = "my-index", attributeName = "title")
        private String title;

        @DynamoDBIndexRangeKey(globalSecondaryIndexName = "my-index", attributeName = "age")
        private String age;
    }