0

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);
}
user1474111
  • 1,356
  • 3
  • 23
  • 47
  • If you had a typo previously, is it possible that the DynamoDB table was created with the old values, and you're trying to test your version against the old key schema? Maybe that table needs to be recreated. – Maurice Dec 21 '22 at 09:47

1 Answers1

0

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;
    }
Leeroy Hannigan
  • 11,409
  • 3
  • 14
  • 31
  • there was typo actually my field name is id actually – user1474111 Dec 21 '22 at 09:20
  • Then it should work, please share the entire working code as well as the output of `DescribeTable` – Leeroy Hannigan Dec 21 '22 at 09:52
  • edited code part and added describe-table output – user1474111 Dec 21 '22 at 13:35
  • I also need to see the rest of your code, where you initialize the client and call mapper.save() – Leeroy Hannigan Dec 21 '22 at 13:48
  • added the bean definition. calling mapper.save pretty straightforward. nothing much in around that. Logged the date which I am passing to mapper and seems as it should be. I am not doing much for client init as well. Using AWSCredentialsProviderChain and should be ok because other repository methods seems to be fine. – user1474111 Dec 21 '22 at 14:01
  • Can you log the value of `properties.getTablePrefix()` and also explicitly set the region in your AmazonDynamoDB instance. – Leeroy Hannigan Dec 21 '22 at 14:13
  • I think there is something wrong with db creation. I have same error when I search by Id. Although table has only hash key it behaves like it has additional element in key for some reason. – user1474111 Dec 21 '22 at 17:00
  • That's why you need to be sure you are pointing at the correct table, which is why you should check region, tableName, endpoint and credentials – Leeroy Hannigan Dec 21 '22 at 18:16
  • I tried to query by index in the app and I am able to receive results. So properties is correct. on aws-cli I am also able to query by id so db creation is also correct. I think something wrong either with my dynamoDb data class and the way I use it while loading data or something wrong with aws-sdk. – user1474111 Dec 22 '22 at 10:36
  • Please can you share the details I asked for. The value of the table override, and how you create the AmazonDynamoDB client, you need to ensure the region and endpoint are correct. I can't help you without further information. – Leeroy Hannigan Dec 22 '22 at 10:50