Conditional update of DynamoDB record using DynamoDBMapper

Keval Padsumbiya
AWS Tip
Published in
2 min readFeb 11, 2023

Sometimes we need to update DynamoDB record only when specific conditions met for existing record of DynamoDB.

Let’s say you have below SampleTable DynamoDB entity/model class:

@NoArgsConstructor
@AllArgsConstructor
@Builder
@Data
@DynamoDBTable(tableName = "sampletable")
public class SampleTable {
private String hashKeyAttribute;
private String rangeKeyAttribute;
private Integer otherAttribute;

@DynamoDBHashKey(attributeName = "hash_key_attribute")
public String getHashKeyAttribute() {
return hashKeyAttribute;
}

@DynamoDBRangeKey(attributeName = "range_key_attribute")
public String getRangeKeyAttribute() {
return rangeKeyAttribute;
}

@DynamoDBAttribute(attributeName = "other_attribute")
public Integer getOtherAttribute() {
return otherAttribute;
}
}

Now, you have a use case to update sampletable only if other_attribute value of existing records is 2 or 5 or 7.

This can be achieved using DynamoDBSaveExpression. Please refer below Java example:

package com.dynamo.db.examples.service;

import com.amazonaws.regions.Regions;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBSaveExpression;
import com.amazonaws.services.dynamodbv2.model.AttributeValue;
import com.amazonaws.services.dynamodbv2.model.ComparisonOperator;
import com.amazonaws.services.dynamodbv2.model.ConditionalCheckFailedException;
import com.amazonaws.services.dynamodbv2.model.ExpectedAttributeValue;
import com.dynamo.db.examples.SampleTable;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DynamoDBConditionalManipulation {

public static void main(String[] args) {
try {
AmazonDynamoDB dynamoDBClient = AmazonDynamoDBClientBuilder.standard()
.withRegion(Regions.US_EAST_1)
.build();

DynamoDBMapper dynamoDBMapper = new DynamoDBMapper(dynamoDBClient);

SampleTable sampleTableRecord = SampleTable.builder()
.hashKeyAttribute("hash_key")
.rangeKeyAttribute("range_key")
.otherAttribute(1)
.build();

// update record only if it exists and other_attribute value is 2 or 5 or 7 only
List<AttributeValue> expectedAttributeValues = Arrays.asList(
new AttributeValue().withN("2"),
new AttributeValue().withN("5"),
new AttributeValue().withN("7")
);

// create save expectedAttributesMap
Map expectedAttributeValuesMap = new HashMap();
expectedAttributeValuesMap.put(
"other_attribute",
new ExpectedAttributeValue()
.withAttributeValueList(expectedAttributeValues)
.withComparisonOperator(ComparisonOperator.IN));

// create save expression
DynamoDBSaveExpression dynamoDBSaveExpression = new DynamoDBSaveExpression();
dynamoDBSaveExpression.setExpected(expectedAttributeValuesMap);

saveDataInDynamoDBWithSaveExpressions(dynamoDBMapper, sampleTableRecord, dynamoDBSaveExpression);

System.out.println("Record saved successfully!");

} catch (Exception ex) {
// handle exception
}
}

public static <R> void saveDataInDynamoDBWithSaveExpressions(DynamoDBMapper dynamoDBMapper,
R recordToSave,
DynamoDBSaveExpression dynamoDBSaveExpressions)
{

try {
dynamoDBMapper.save(recordToSave, dynamoDBSaveExpressions);
} catch (ConditionalCheckFailedException ex) { // thrown while dynamoDBSaveExpressions validation fails
// handle exception
} catch (Exception ex) {
// handle exception
}
}

}

Gradle dependency required is:

implementation group: 'com.amazonaws', name: 'aws-java-sdk-dynamodb', version: '1.11.+'

You can also use CONTAINS, BETWEEN, GT, LS, EQ, BEGINS_WITH etc as a comparison operator.

ConditionalCheckFailedException will be thrown if any of the ExpectedAttributeValue’s validation fails.

Thank you for reading, please follow if you like the article.

Subscribe to stay tuned for upcoming articles.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Published in AWS Tip

Best AWS, DevOps, Serverless, and more from top Medium writers .

Written by Keval Padsumbiya

Competitive Programmer and Software Engineer with experience in Java, Spring Boot, AWS, Jooq, SQL, Terraform etc

No responses yet

What are your thoughts?