You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have a requirement where I need to be able to serialize a DynamoDB item to a string and then deserialize it as an item again. I do the serialization by creating a TableSchema object, calling itemToMap, and then using Gson to convert the map to a JSON string. Similarly, I do the deserialization by converting the string to a map and then calling mapToItem from the same table schema to get the item.
However, when the serialization occurs, the JSON string for an attribute value looks like the following:
where this corresponds to a list of Dimension objects, which looks like:
@DynamoDbBean
data class Dimension(var name: String? = null)
The issue here is that other collections in the attribute value get initialized as an empty data structure, instead of not being initialized in the first place. This leads to an error during deserialization when using the ListAttributeConverter.
Expected Behavior
I expected that the ListAttributeConverter can convert lists of custom objects correctly and deserialize the JSON as an object correctly.
Current Behavior
Instead it fails with the following error:
software.amazon.awssdk.enhanced.dynamodb.internal.converter.attribute.ListAttributeConverter cannot convert an attribute of type M into the requested type interface java.util.List
java.lang.IllegalStateException: software.amazon.awssdk.enhanced.dynamodb.internal.converter.attribute.ListAttributeConverter cannot convert an attribute of type M into the requested type interface java.util.List
at software.amazon.awssdk.enhanced.dynamodb.internal.converter.TypeConvertingVisitor.defaultConvert(TypeConvertingVisitor.java:188)
at software.amazon.awssdk.enhanced.dynamodb.internal.converter.TypeConvertingVisitor.convertMap(TypeConvertingVisitor.java:113)
at software.amazon.awssdk.enhanced.dynamodb.internal.converter.TypeConvertingVisitor.convert(TypeConvertingVisitor.java:88)
at software.amazon.awssdk.enhanced.dynamodb.internal.converter.attribute.EnhancedAttributeValue.convert(EnhancedAttributeValue.java:428)
at software.amazon.awssdk.enhanced.dynamodb.internal.converter.attribute.ListAttributeConverter$Delegate.transformTo(ListAttributeConverter.java:156)
at software.amazon.awssdk.enhanced.dynamodb.internal.converter.attribute.ListAttributeConverter.transformTo(ListAttributeConverter.java:121)
at software.amazon.awssdk.enhanced.dynamodb.internal.converter.attribute.ListAttributeConverter.transformTo(ListAttributeConverter.java:83)
This is because when the enhanced attribute value is trying to determine how to parse the attribute value (ref),
if (attributeValue.hasM()) {
return EnhancedAttributeValue.fromMap(attributeValue.m());
}
hasM returns true and it fails to parse the list as a map. hasM returns True, because it checks if m is null instead of empty.
Reproduction Steps
Create an attribute value of type list
Serialize the attribute value using Gson.toJson
Deserialize the attribute value using Gson.fromJson
Call EnhancedAttributeValue.fromAttributeValue to reproduce the failure
Possible Solution
Two quick fixes:
Use a switch statement on the attribute value type instead of using the boolean functions
Modify hasM to check if the field is an empty dictionary
Long term - I don't think it makes sense to even allow a state where an attribute value has multiple values. It probably makes more sense to throw an error if we attempt to set multiple values.
Additional Information/Context
This may be an issue in the serialization itself (i.e. why are multiple fields written for each attribute value). If this isn't the correct way to serialize an AttributeValue as a JSON, please suggest an alternative method.
AWS Java SDK version used
2.20.40
JDK version used
11
Operating System and version
MacOS Ventura 13.4
The text was updated successfully, but these errors were encountered:
@ndodda-amazon we don't consider this a bug, it's a use case we don't support. Initializing the attributes with empty values was a design decision of the DDB Enhanced Client. Also, I don't think we can change hasM to check for empty values without doing a breaking change.
We do have a open feature request to support a native JSON attribute converter, feel free to add a 👍 - #2162
Comments on closed issues are hard for our team to see.
If you need more assistance, please open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.
Describe the bug
I have a requirement where I need to be able to serialize a DynamoDB item to a string and then deserialize it as an item again. I do the serialization by creating a
TableSchema
object, callingitemToMap
, and then using Gson to convert the map to a JSON string. Similarly, I do the deserialization by converting the string to a map and then callingmapToItem
from the same table schema to get the item.However, when the serialization occurs, the JSON string for an attribute value looks like the following:
where this corresponds to a list of
Dimension
objects, which looks like:The issue here is that other collections in the attribute value get initialized as an empty data structure, instead of not being initialized in the first place. This leads to an error during deserialization when using the
ListAttributeConverter
.Expected Behavior
I expected that the ListAttributeConverter can convert lists of custom objects correctly and deserialize the JSON as an object correctly.
Current Behavior
Instead it fails with the following error:
This is because when the enhanced attribute value is trying to determine how to parse the attribute value (ref),
hasM
returns true and it fails to parse the list as a map.hasM
returns True, because it checks ifm
is null instead of empty.Reproduction Steps
Gson.toJson
Gson.fromJson
EnhancedAttributeValue.fromAttributeValue
to reproduce the failurePossible Solution
Two quick fixes:
hasM
to check if the field is an empty dictionaryLong term - I don't think it makes sense to even allow a state where an attribute value has multiple values. It probably makes more sense to throw an error if we attempt to set multiple values.
Additional Information/Context
This may be an issue in the serialization itself (i.e. why are multiple fields written for each attribute value). If this isn't the correct way to serialize an AttributeValue as a JSON, please suggest an alternative method.
AWS Java SDK version used
2.20.40
JDK version used
11
Operating System and version
MacOS Ventura 13.4
The text was updated successfully, but these errors were encountered: