DynamoDBTypeConverter not working as expected

1.3k views Asked by At

First, the code that runs correctly: The content in DynamoDB table is :

"test_field" : "x:x:x"

Entity POJO has:

@DynamoDBTypeConverted(converter = SingleFieldConverter.class)
@DynamoDBAttribute(attributeName = "test_field")
private SingleField singleField;

with appropriate getter and setter methods. Converter class is:

public class SingleFieldConverter implements DynamoDBTypeConverter<String, SingleField> {

@Override
public String convert(SingleField singleField) {
   // removed for clarity
}

@Override
public SingleField unconvert(String s) {
   // removed for clarity
}

and it works!

But when I change the DynamoDB item to have:

"test_field" : [
        "x:x:x",
        "x:x:x"
        ]
      

and my POJO object to:

@DynamoDBTypeConverted(converter = SingleFieldConverter.class)
@DynamoDBAttribute(attributeName = "test_field")
private List<SingleField> singleField;

and converter class to be like:

public class SingleFieldConverter implements DynamoDBTypeConverter<String, List<SingleField>> {

@Override
public String convert(List<SingleField> singleField) {
   // removed for clarity
}

@Override
public List<SingleField> unconvert(String s) {
   // removed for clarity
}

}

it throws:

DynamoDBMappingException
. . . . . [test_field]; could not unconvert attribute
 . . .Caused by: com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMappingException: expected S in value {L: [{S: x:x:x:,}, {S: x:x:x:,}],}

Similar examples I found on the web allegedly work, but my example does not. What am I missing, please help?

1

There are 1 answers

0
Martin P. On

Based on the error it looks like the converter return a String. To avoid confusion, I suggest to rename the SingleFieldConverter to SingleFieldListConverter.

I confirm that complex type are supported. I use this Generic without any problems:

public abstract class MapToJsonStringConverter<K, V> implements DynamoDBTypeConverter<String, Map<K, V>> {
    private final static ObjectMapper mapper= new ObjectMapper();
    
    @Override
    public String convert(Map<K, V> map) {
        try {
            return mapper.writeValueAsString(map);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }
}

Each unconvert are usage specific.