I am trying to setup an Optimistic version check before I update the record in DynamoDB.
But I keep getting ConditionalCheckFailedException from the first item save - when there is no hash key existing.
Can someone tell me what's wrong in my code?
Here's my code
final DynamoDBMapperConfig.Builder builder = new DynamoDBMapperConfig.Builder();
builder.setConsistentReads(DynamoDBMapperConfig.ConsistentReads.CONSISTENT);
builder.setTableNameOverride(new DynamoDBMapperConfig.TableNameOverride(tableName));
DynamoDBMapperConfig mapperConfig = builder.build();
this.dynamoDBMapper = new DynamoDBMapper(amazonDynamoDB, mapperConfig);
@Data
@DynamoDBTable(tableName = "OVERRIDE_AT_RUNTIME")
public class ItemRecord
{
public static final String CONTENT_ID = "content_id";
public static final String ACTION_COUNT = "action_count";
private static final String VERSION = "version";
@DynamoDBHashKey(attributeName = CONTENT_ID)
private String contentId;
@DynamoDBAttribute(attributeName = ACTION_COUNT)
private int actionCount;
@DynamoDBVersionAttribute(attributeName = VERSION)
private long version;
public TitleMatchProgressRecord() {}
public TitleMatchProgressRecord(final String contentId)
{
this.contentId = contentId;
this.actionCount = 0;
}
@DynamoDBIgnore
public void incrementActionCount()
{
actionCount++;
}
}
try {
ItemRecord itemRecord = loadRecord(contentId);
if (itemRecord == null) { // first item
itemRecord = new ItemRecord(contentId);
itemRecord.incrementActionCount();
DynamoDBSaveExpression saveExpression = new DynamoDBSaveExpression();
final Map<String, ExpectedAttributeValue> expectedAttributes = new HashMap<>();
expectedAttributes.put(ItemRecord.CONTENT_ID, new ExpectedAttributeValue(false));
saveExpression.setExpected(expectedAttributes);
dynamoDBMapper.save(itemRecord, saveExpression);
} else {
itemRecord.incrementActionCount();
itemRecord.resetLastModifiedAt();
dynamoDBMapper.save(itemRecord);
}
} catch (ConditionalCheckFailedException e) {
// retry
}
Error trace:
[testng] com.amazonaws.services.dynamodbv2.model.ConditionalCheckFailedException: The conditional request failed (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ConditionalCheckFailedException; Request ID: UV4V9BSIE78ETRQC9LG4BOB23; Proxy: null)
[testng] at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleErrorResponse(AmazonHttpClient.java:1811)
[testng] at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleServiceErrorResponse(AmazonHttpClient.java:1395)
[testng] at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1371)
[testng] at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1145)
[testng] at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:802)
[testng] at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:770)
[testng] at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:744)
[testng] at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:704)
[testng] at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:686)
[testng] at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:550)
[testng] at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:530)
[testng] at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.doInvoke(AmazonDynamoDBClient.java:5110)
[testng] at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.invoke(AmazonDynamoDBClient.java:5077)
[testng] at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.executeUpdateItem(AmazonDynamoDBClient.java:4696)
[testng] at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.updateItem(AmazonDynamoDBClient.java:4662)
[testng] at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper$SaveObjectHandler.doUpdateItem(DynamoDBMapper.java:871)
[testng] at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper$2.executeLowLevelRequest(DynamoDBMapper.java:611)
[testng] at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper$SaveObjectHandler.execute(DynamoDBMapper.java:750)
[testng] at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.save(DynamoDBMapper.java:640)
[testng] at com.amazonaws.services.dynamodbv2.datamodeling.AbstractDynamoDBMapper.save(AbstractDynamoDBMapper.java:123)
attribute_not_exists(x) OR x = y) is not supported by DynamoDBMapper. github.com/aws/aws-sdk-java/issues/534