'DynamoDBMapper converting variable datatypes

I have a Lambda function written in java that talks to a DynamoDB. For one table I have to change the type of a property from a plain integer to a custom object that I will convert to a Set (DynamoDB SS datatype) on saving. But since there are already documents in this table, when reading from it this property could either have an integer (N) datatype or the SS datatype.

I already have a converter for my custom object that implements DynamoDBTypeConverter, CustomObject>. To handle the db datatype potentially being an integer, I tried changing this to DynamoDBTypeConverter but unfortunately it seems the java sdk does not allow the dynamodb type to be a generic Object.

Is there any way to handle these multiple datatypes with the converter? Will I have to convert all values in the database seperately? Or should I just use an entirely new property and deprecate the use of the old integer property?



Solution 1:[1]

Since the DynamoDBMapper explicitly doesn't allow conversion type to be Object (as seen in the com.amazonaws.services.dynamodbv2datamodeling.ConvertibleType.of(DynamoDBTypeConverter<?,T>) method), but Object is the only common parent of the two classes I need to handle I could not think of any way to handle this through reflection.

Instead I am just using a DynamoDBTypeConverter, CustomObject> to convert the object, but in my Model that contains a CustomObject (that was previously an int) I have used the @DynamoDBAttribute(attributeName="newAttName") to point the field to a different attribute in the database. This unfortunately means that all data that was in the previous attribute is lost, but that seemed to be the most efficient way of dealing with this issue in my case. Hopefully this might help somebody else who encounters this problem.

Solution 2:[2]

I have struggle with this issue, looking around everywhere before finding a solution. DynamoDBTypeConverter won't indeed accept the Object class as input.

But you can use the dynamo class AttributeValue to make it work. In my case I had an attribute that was an Integer, but that I wanted to change to String. In the dynamo table it would either be an Integer or a String. My DynamoDBTypeConverter is looking like this:

@Override
public AttributeValue convert(String string) {
    return new AttributeValue().withS(string);
}

@Override
public String unconvert(AttributeValue attributeValue) {
    if (attributeValue.getS() != null) {
        return attributeValue.getS();
    } else {
        return attributeValue.getN();
    }
}

With AttributeValue, you can check what kind of type you have, and then convert it accordingly to the output you want (in my case a String).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Geoff McLennan
Solution 2 Fabrice