Description
Describe the bug
TableSchema.fromBean(Bean.class).itemToMap(bean, false)
returns a map without members of any @DynamoDbFlatten
'd members if the flattened member is null even though ignoreNulls
is set to false.
Expected Behavior
TableSchema::itemToMap
should return a map that contains a consistent representation of null top-level (non-flattened) attributes and flattened attributes when their "parent" member is null and ignoreNulls
is set to false. In other words, the members of any flattened attributes should be included with a null attribute value when their enclosing member is null.
Current Behavior
TableSchema::itemToMap
returns null attribute values only for top-level members.
Steps to Reproduce
@DynamoDbBean
public class Bean {
private String attribute;
private Flattened flattened;
public String getAttribute() { return attribute; }
public void setAttribute(String attribute) { this.attribute = attribute; }
@DynamoDbFlatten
public Flattened getFlattened() { return flattened; }
public void setFlattened(Flattened flattened) { this.flattened = flattened; }
}
@DynamoDbBean
public class Flattened {
private String flattenedAttribute;
public String getFlattenedAttribute() { return flattenedAttribute; }
public void setFlattenedAttribute(String flattenedAttribute) { this.flattenedAttribute = flattenedAttribute; }
}
public class TestItemToMap {
public static void main(String[] args) {
TableSchema<Bean> schema = TableSchema.fromBean(Bean.class);
Bean bean = new Bean();
Map<String, AttributeValue> mapWithNulls = schema.itemToMap(bean, false);
System.out.println(Arrays.toString(mapWithNulls.entrySet().toArray()));
}
}
actual result
[attribute=AttributeValue(NUL=true)]
expected result
[attribute=AttributeValue(NUL=true),flattenedAttribute=AttributeValue(NUL=true)]
Possible Solution
It appears this is happening inside of StaticImmutableTableSchema::itemToMap.
Context
I'm writing custom update expressions and had to have explicit nulls when comparing attribute maps.
Kotlin:
val difference = Maps.difference(existingAttributeMap, updatedAttributeMap)
val attributesToUpdate = difference
.entriesDiffering().mapValues { (_, value) -> value.rightValue() } // mutated attributes
.plus(difference.entriesOnlyOnRight()) // previously-null attributes that are being set
.plus(difference.entriesOnlyOnLeft().mapValues { nullAttributeValue }) // previously-set attributes that are being nullified
Your Environment
- AWS Java SDK version used: 2.16.87