Reputation: 879
I want to update existing token item with last_accessed_on
column (which is new). I tried below code which is failing.
Please point me what is wrong here.
//dynamoDB is initialized with config and it is good.
Table table = dynamoDB.getTable("Token");
UpdateItemSpec updateItemSpec = new UpdateItemSpec()
.withPrimaryKey("GUID", "guidHashed")
.withUpdateExpression("set #name = :val1")
.withNameMap(new NameMap().with("#name", "last_accessed_on"))
.withValueMap(new ValueMap().withLong(":val1", System.currentTimeMillis()));
Below is the DTO object.
@DynamoDBTable(tableName = "Token")
public class TokenItem {
@DynamoDBHashKey(attributeName = "GUID")
private String guid;
@DynamoDBRangeKey(attributeName = "type")
private String type;
@DynamoDBAttribute(attributeName = "last_accessed_on")
private long lastAccessedOn;
//getter and setters
}
Error:
com.amazonaws.services.dynamodbv2.model.AmazonDynamoDBException: The provided key element does not match the schema (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException; Request ID: FNEPHSAEMVJF66Q9ASUAAJG)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleErrorResponse(AmazonHttpClient.java:1660)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1324)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1074)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:745)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:719)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:701)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:669)
at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:651)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:515)
at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.doInvoke(AmazonDynamoDBClient.java:3768)
at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.invoke(AmazonDynamoDBClient.java:3737)
at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.executeUpdateItem(AmazonDynamoDBClient.java:3448)
at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.updateItem(AmazonDynamoDBClient.java:3416)
at com.amazonaws.services.dynamodbv2.document.internal.UpdateItemImpl.doUpdateItem(UpdateItemImpl.java:102)
at com.amazonaws.services.dynamodbv2.document.internal.UpdateItemImpl.updateItem(UpdateItemImpl.java:86)
at com.amazonaws.services.dynamodbv2.document.Table.updateItem(Table.java:225)
Upvotes: 0
Views: 346
Reputation: 7669
You are missing the range key from your UpdateItemSpec
. You need to use withPrimaryKey(String hashKeyName, Object hashKeyValue, String rangeKeyName, Object rangeKeyValue)
instead of the method that accepts only the hash key. Also, type
is a reserved word in DynamoDB, so you will need to add it to the NameMap.
The fixed UpdateItemSpec would be like this.
Table table = dynamoDB.getTable("Token");
UpdateItemSpec updateItemSpec = new UpdateItemSpec()
.withPrimaryKey("GUID", ":guid", "#type", ":type")
.withUpdateExpression("set #name = :val1")
.withNameMap(new NameMap()
.with("#name", "last_accessed_on")
.with("#type", "type"))
.withValueMap(new ValueMap()
.withLong(":val1", System.currentTimeMillis())
.withString(":guid", /* put the guid here */)
.withString(":type", /* put the type here */));
Upvotes: 1
Reputation: 421
Did you try DynamoDBMapper dyanmoDbMapper = new DynamoDBMapper(client, yourConfig);
DynamoDBQueryExpression<Token> qExp = new DynamoDBQueryExpression<Timesheet>()
.withKeyConditionExpression(" GUID =:GUID and type =:type")
.withExpressionAttributeValues(mapOfGuiAndTypeValues).withScanIndexForward(false)
.withConsistentRead(false);
QueryResultPage< Token> queryPage= dyanmoDbMapper.queryPage(Token.class, qExp);
once you have retrieved the object then update with last access value and save
dyanmoDbMapper.save(updatedObject);
Upvotes: 0