Skip to content

[DynamoDbEnhancedClient] TableSchema::itemToMap doesn't respect ignoreNulls with null @DynamoDbFlattened members #2540

Open
@neumannk

Description

@neumannk

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugThis issue is a bug.dynamodb-enhancedp2This is a standard priority issue

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions