Reputation: 31
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?
Upvotes: 1
Views: 5265
Reputation: 31
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>.
Upvotes: 2
Reputation: 2366
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);
Upvotes: 0