20

I'm trying to store an array of strings within an AWS DynamoDB table. For the most part this array will be populated with at least one string. However there is the case where the array could be empty.

I've created a DynamoDB model in a Java Lambda function that has a set of strings as one of it's properties. If I try to save a DynamoDB model when the set of strings is empty it gives me an error saying I can't store an empty set in DynamoDB.

So my question is, how would handle removing that set property when it's empty from my model before I save / update it in the DynamoDB?

Here's an example of the model.

@DynamoDBTable(tableName = "group")
public class Group {
    private String _id;
    private Set<String> users;

    @Null
    @DynamoDBHashKey
    @DynamoDBAutoGeneratedKey
    public String getId() {
        return _id;
    }

    public void setId(final String id) {
        _id = id;
    }

    @DynamoDBAttribute
    public Set<String> getUsers(){
        return users;
    }

    public void setUsers(final Set<String> users) {
        this.users = users;
    }

    public void addUser(String userId) {
        if(this.users == null){
            this.setUsers(new HashSet<String>(Arrays.asList(userId)));
        }else{
            this.getUsers().add(userId);
        }
   }
}

First time when I will create a group. It could have no user, or it could have one or more user.

2
  • Based on further conversations I've had regarding this with AWS technical support it sounds like the accepted practice is to actually delete the existing item and recreate a new item with the same primary index leaving off the property that would be null. I tried this and didn't have any luck with it. Commented May 14, 2016 at 12:44
  • That means we can not use any Java POJO class for this kind of situation? Commented May 16, 2016 at 5:10

2 Answers 2

2

This is somewhat of an old question but the way I would solve this problem is with a custom DynamoDBMarshaller.

Making use of the @DynamoDBMarshalling annotation, you can decorate the POJO accessor methods in order to dictate to the DynamoDB mapper which marshaller class to use to serialize and deserialize the set of strings. This way you get control over the special use cases.

Here is also a link to an AWS blog post with an example

The one caveat with the approach above is the customer marshaller solution serializes and deserializes to/from string so the representation in the database wouldn't be a set per se. However, I wouldn't consider that to be too bad.

Another approach might be to use the Document API, instead of the object mappers, which gives you full control over the items. Though I would still go for custom mapper with string backing.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! I will give try to implement this.
2

When it came down to the actual problem it was because the code I inherited had the SaveBehavior on the DynamoDBMapperConfig set to UPDATE_SKIP_NULL_ATTRIBUTES which skips null values and therefore will never remove them from DynamoDB. See this post of explanations of all the different save behaviors. https://java.awsblog.com/post/Tx1MH3BFPW8FX6W/Using-the-SaveBehavior-Configuration-for-the-DynamoDBMapper

To elaborate on this a little bit further.

I'm setting my DynamoDBMapperConfig.SaveBehavior as such within my JAVA project.

_dynamoDBMapperConfig = new DynamoDBMapperConfig.Builder() .withSaveBehavior(SaveBehavior.UPDATE) .withTableNameResolver(TABLE_NAME_RESOLVER) .withConversionSchema(ConversionSchemas.V2) .build();

Then whenever you update a model that has a mapped @DynamoDBAttribute you also need to set the particular value to (null).

user.setFirstName(null)

This was the easiest way I found to be able to remove attributes from a DynamoDB Entry.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.