18

I'm using DynamoDBMapper and would like to conditionally save if and only if the hashkey and range key combination does not exist. I know there are ways to use UUIDs to reduce the possibility of a collision but I would like to protect myself by using conditional saves.

I came across this article that uses DynamoDBSaveExpression however I'm not able to specify that the condition is "hashkey AND rangekey" cannot exist. The API specifies a withConditionalOperator method but I'm not able to see this in my class. I am using the latest aws java sdk also from here.

Any suggestions on how to conditionally save? Or what I may be doing incorrectly?

n00b
  • 5,843
  • 11
  • 52
  • 82

1 Answers1

36
DynamoDBSaveExpression saveExpression = new DynamoDBSaveExpression();
Map<String, ExpectedAttributeValue> expectedAttributes = 
    ImmutableMap.<String, ExpectedAttributeValue>builder()
        .put("hashKey", new ExpectedAttributeValue(false))
        .put("rangeKey", new ExpectedAttributeValue(false))
        .build();
saveExpression.setExpected(expectedAttributes);
saveExpression.setConditionalOperator(ConditionalOperator.AND);
try {
    dynamoDBMapper.save(objectToSave, saveExpression);
} catch (ConditionalCheckFailedException e) {
    //Handle conditional check
}

This uses the public ExpectedAttributeValue(Boolean exists) constructor, which just internally calls setExists.

mkobit
  • 43,979
  • 12
  • 156
  • 150
  • Thanks Mike. I realised that I didn't sync my IDE with the gradle build and so the latest AWS SDK wasn't available in the IDE. Once I synced it the setConditionalOperator method became available. Thanks for your answer. It's correct so I have marked it as such. – n00b Jan 22 '15 at 21:57
  • Is that setConditionalOperator required? Is it not default to validate all the condition? – iamprem Oct 05 '16 at 19:20
  • 1
    Found it! "If you omit ConditionalOperator, then AND is the default." from here under the conditional operator section: http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html – iamprem Oct 06 '16 at 00:58
  • 3
    I tries the exact same thing and it does not work for me. In my case they are not hashKey and rangeKey but on different attributes. Could you please help me. – Ravi Krishna P Oct 15 '16 at 03:01
  • I have a doubt - why use AND, rather than OR? Shouldn't it be: (hashKey does not exist) OR (rangeKey does not exist)? [Ref - http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/model/ExpectedAttributeValue.html#withExists-java.lang.Boolean- ] – aalosious Jan 18 '17 at 12:29
  • @aalosious For the combination of `hashKey` and `rangeKey`, it will not really matter. See [this answer](https://stackoverflow.com/questions/32833351/dynamodb-put-item-if-hash-or-hash-and-range-combination-doesnt-exist/32833726#32833726) for an explanation of that. – mkobit Jan 18 '17 at 15:00
  • 1
    @RaviKrishnaP conditional check does not work on attributes other than hash or range key in dynamoDB – Somil Jan 28 '20 at 11:50