1

I am using a DynamoDB-table with DynamoDBAttributeType.M maps nested in one another. The field of my table I'm having problems with looks like this:

"Data": {
  "EnglishName": "Balcony",
  "High": {
    "Status": true,
    "Triggered": true,
    "Value": 5
  },
  "Low": {
    "Status": true,
    "Triggered": false,
    "Value": 1
  },
  "TagName": "tag1"
}

all the keys of the map are Strings and some of the values are Strings and some are maps. In my Java code that data is represented by a class, which is an attribute of another class, which represents whole table. Attributes 'Low' and 'High' are also represented by Java class and attributes of data class.

I have tried to map it to Java object using many ways, mostly by DynamoDBTypeConverter. Hardest part is that I can't find any information about this with Google. I only found one example of converter class where attribute type is S not M.

I keep on getting error:

could not unconvert attribute

How this can be done?

2 Answers 2

2

Finally I have a functioning solution. Basically the answer is to use Map<String, Attributevalue> and desired object type in DynamoDBTypeConverter like this:

public class DataConverter implements DynamoDBTypeConverter<Map<String, AttributeValue>, Data> {

@Override
public Map<String, AttributeValue> convert(Data data) {
    
    ObjectMapper mapper = new ObjectMapper();
    
    Item item = new Item()
           .withString("englishName", data.getEnglishName())
           .withMap("high", mapper.convertValue(data.getHigh(), Map.class))
           .withMap("low", mapper.convertValue(data.getLow(), Map.class))
           .withString("tagName", data.getTagName());

    return ItemUtils.toAttributeValues(item);
}

@Override
public Data unconvert(Map<String, AttributeValue> data) {
    Data tagData = new Data();
    try {
        ObjectMapper mapper = new ObjectMapper();
        String item = ItemUtils.toItem(data).toJSON();
        JsonNode json = mapper.readTree(item);
        tagData = mapper.convertValue(json, Data.class);
        
    } catch (JsonProcessingException ex) {
        Logger.getLogger(TagDataConverter.class.getName()).log(Level.SEVERE, null, ex);
    }       
    return tagData;
}    

I also needed to write type converters to attributes that are objects and annotate them in class:

public class Data {

    private String tagName;

    private String englishName;

    @DynamoDBTypeConverted(converter = AlertConverter.class)
    private Alert low;

    @DynamoDBTypeConverted(converter = AlertConverter.class)
    private Alert high;

The AlertConverter.class is an ordinary DynamoDBTypeConverter that takes in <String, Alert>.

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

Comments

0

Have you tried using a tool like Gson? If you're getting back the DynamoDB response as a JSON string, try this:

Gson gson = new Gson();
Data data = gson.fromJson(jsonString, Data.class);

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.