Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DynamoDBMapper save only if object doesn't exist

Using the Java DynamoDBMapper, how can I save an object only if it doesn't already exist (based on primary key). If it does exist, I want an exception or failure to be thrown, rather than having the existing entry updated.

like image 931
Nosrettap Avatar asked Mar 26 '15 19:03

Nosrettap


2 Answers

I believe you should be able to do this with a DynamoDbSaveExpression object that can apply to the mapper.

There's a tutorial on the AWS site here, code shown below:

try {
    DynamoDBSaveExpression saveExpression = new       DynamoDBSaveExpression();
    Map expected = new HashMap();
    expected.put("status", new ExpectedAttributeValue().withExists(false));

    saveExpression.setExpected(expected);

    mapper.save(obj, saveExpression);
} catch (ConditionalCheckFailedException e) {
    // This means our save wasn't recorded, since our constraint wasn't met
    // If this happens, the worker can simply look for a new task to work on
}
like image 135
tddmonkey Avatar answered Nov 18 '22 13:11

tddmonkey


Here's the correct way to implement this with the DynamoDBMapper:

User newUser = new User();
newUser.setUsername(username);
newUser.setPassword(password);

DynamoDBSaveExpression saveExpr = new DynamoDBSaveExpression();
saveExpr.setExpected(new ImmutableMap.Builder()
.put("username", new ExpectedAttributeValue(false)).build());

dynamoDBMapper.save(newUser, saveExpr);

Source: https://blog.jayway.com/2013/08/24/create-entity-if-not-exists-in-dynamodb-from-java/

EDIT: Here's my implementation of it in practice. Extremely easy to implement:

public Statement saveIfNotExist(Statement statement) throws ConditionalCheckFailedException {
    return mapper.save(statement, new DynamoDBSaveExpression().withExpected(ImmutableMap.of("id", new ExpectedAttributeValue(false))));
}

with passing unit test:

@Test(expectedExceptions = ConditionalCheckFailedException.class)
public void shouldNotProcessIdenticalStatementUpdateInstances() {
    Statement statement1 = StatementTestBuilder.valid().build();
    Statement statement2 = StatementTestBuilder.valid().withId(statement1.getId()).build();

    statementRepository.saveIfNotExist(statement1);
    statementRepository.saveIfNotExist(statement2);
}
like image 42
fIwJlxSzApHEZIl Avatar answered Nov 18 '22 12:11

fIwJlxSzApHEZIl