AWS Developer Tools Blog
Using the SaveBehavior Configuration for the DynamoDBMapper
The high-level save API of DynamoDBMapper provides a convenient way of persisting items in an Amazon DynamoDB table. The underlying implementation uses either a PutItem request to create a new item or an UpdateItem request to edit the existing item. In order to exercise finer control over the low-level service requests, you can use a SaveBehavior configuration to specify the expected behavior when saving an item. First, let’s look at how to set a SaveBehavior configuration. There are two ways of doing it:
- You can specify the default
SaveBehaviorwhen constructing a new mapper instance, which will affect all save operations from this mapper:// All save operations will use the UPDATE behavior by default DynamoDBMapper mapper = new DynamoDBMapper(dynamoDBClient, new DynamoDBMapperConfig(SaveBehavior.UPDATE)); - You can also force a
SaveBehaviorfor a particular save operation:// Force this save operation to use CLOBBER, instead of the default behavior of this mapper mapper.save(obj, new DynamoDBMapperConfig(SaveBehavior.CLOBBER));
The next step is to understand different SaveBehavior configurations. There are four different configurations you can choose from: UPDATE(default), UPDATE_SKIP_NULL_ATTRIBUTES, CLOBBER, and APPEND_SET. When you add a new item to the table, using any of the four configurations has the same effect—puts the item as specified in the POJO (though it might be achieved by different service request calls). However, when it comes to updating an existing item, these SaveBehavior configurations have different results, and you need to choose the appropriate one according to how you want to control your data. In order to explain this, let’s walk through an example of using different SaveBehavior configurations to update an item specified by the same POJO:
- Table schema:
AttributeName key modeled_scalar modeled_set unmodeled KeyType Hash Non-key Non-key Non-key AttributeType Number String String set String - POJO class definition:
@DynamoDBTable(tableName="TestTable") public class TestTableItem { private int key; private String modeledScalar; private Set<String> modeledSet; @DynamoDBHashKey(attributeName="key") public int getKey() { return key; } public void setKey(int key) { this.key = key; } @DynamoDBAttribute(attributeName="modeled_scalar") public String getModeledScalar() { return modeledScalar; } public void setModeledScalar(String modeledScalar) { this.modeledScalar = modeledScalar; } @DynamoDBAttribute(attributeName="modeled_set") public Set<String> getModeledSet() { return modeledSet; } public void setModeledSet(Set<String> modeledSet) { this.modeledSet = modeledSet; } } - Existing item:
{ "key" : "99", "modeled_scalar" : "foo", "modeled_set" : [ "foo0", "foo1" ], "unmodeled" : "bar" } - POJO object:
TestTableItem obj = new TestTableItem(); obj.setKey(99); obj.setModeledScalar(null); obj.setModeledSet(Collections.singleton("foo2");
Then let’s look at the effect of using each SaveBehavior configuration:
-
UPDATE(default)UPDATE will not affect unmodeled attributes on a save operation, and a null value for the modeled attribute will remove it from that item in DynamoDB.
Updated item:
{ "key" : "99", "modeled_set" : [ "foo2" ], "unmodeled" : "bar" } -
UPDATE_SKIP_NULL_ATTRIBUTESUPDATE_SKIP_NULL_ATTRIBUTES is similar to UPDATE, except that it ignores any null value attribute(s) and will NOT remove them from that item in DynamoDB.
Updated item:
{ "key" : "99", "modeled_scalar" : "foo", "modeled_set" : [ "foo2" ], "unmodeled" : "bar" } -
CLOBBERCLOBBER will clear and replace all attributes, including unmodeled ones, (delete and recreate) on save.
Updated item:
{ "key" : "99", "modeled_set" : [ "foo2" ] } -
APPEND_SETAPPEND_SET treats scalar attributes (String, Number, Binary) the same as UPDATE_SKIP_NULL_ATTRIBUTES does. However, for set attributes, it will append to the existing attribute value, instead of overriding it.
Updated item:
{ "key" : "99", "modeled_scalar" : "foo", "modeled_set" : [ "foo0", "foo1", "foo2" ], "unmodeled" : "bar" }
Here is a summary of the differences between these SaveBehavior configurations:
| SaveBehavior | On unmodeled attribute | On null-value attribute | On set attribute |
|---|---|---|---|
| UPDATE | keep | remove | override |
| UPDATE_SKIP_NULL_ATTRIBUTES | keep | keep | override |
| CLOBBER | remove | remove | override |
| APPEND_SET | keep | keep | append |
As you can see, SaveBehavior provides great flexibility on how to update your data in Amazon DynamoDB. Do you find these SaveBehavior configurations easy to use? Are there any other save behaviors that you need? Leave your comment here and help us improve our SDK!