Skip to content

TableSchema.itemToMap() ignoreNulls flag not propagated #2504

Open
@productivityindustries

Description

@productivityindustries

Describe the bug

When calling TableSchema.itemToMap() method to convert a table bean into a map of names/attributes, the ignoreNulls flag is not propagated to nested beans.

Expected Behavior

The generated map should not contains any AttributeValue with nul=true even in nested maps.

Current Behavior

Currently, converting items to maps with ignoreNulls=true might generate AttributeValue with nul=true elements.

Steps to Reproduce

public static final StaticTableSchema CHAPTER_SCHEMA = StaticTableSchema.builder(Chapter.class)
.newItemSupplier(Chapter::new)
.addAttribute(Integer.class, a -> a.name("page").getter(Chapter::getPage).setter(Chapter::setPage))
.addAttribute(String.class, a -> a.name("text").getter(Chapter::getText).setter(Chapter::setText))
.build();

public static final StaticTableSchema BOOK_SCHEMA = StaticTableSchema.builder(Book.class)
.newItemSupplier(Book::new)
.addAttribute(String.class, a -> a.name("id").tags(primaryPartitionKey()).getter(Book::getId).setter(Book::setId))
.addAttribute(EnhancedType.documentOf(Chapter.class, CHAPTER_SCHEMA),
a -> a.name("chapter").getter(Book::getChapter).setter(Book::setChapter))
.addAttribute(EnhancedType.mapOf(EnhancedType.of(String.class), EnhancedType.documentOf(Chapter.class, CHAPTER_SCHEMA)),
a -> a.name("chapters").getter(Book::getChapters).setter(Book::setChapters))
.build();

@DynamoDbBean
public static class Book {

private String id;
private Chapter chapter;
private Map<String, Chapter> chapters;

public Book() { }
public Book(String id) { setId(id); }

@DynamoDbPartitionKey
public String getId() {return id;}
public void setId(String id) {this.id = id;}
public Chapter getChapter() {return chapter;}
public void setChapter(Chapter chapter) {this.chapter = chapter;}
public Map<String, Chapter> getChapters() {return chapters;}
public void setChapters(Map<String, Chapter> chapters) {this.chapters = chapters;}

}

@DynamoDbBean
public static class Chapter {

private Integer page;
private String text;

public Integer getPage() {return page;}
public void setPage(Integer page) {this.page = page;}
public String getText() {return text;}
public void setText(String text) {this.text = text;}

}

@test
public void testStatic() throws Exception {
DynamoDbEnhancedClient enhancedClient = getEnhancedClient();
DynamoDbTable table = enhancedClient.table("books", BOOK_SCHEMA);
table.createTable();

Chapter chapter = new Chapter();
chapter.setPage(1);
Book book = new Book("123");
book.setChapter(chapter);
book.setChapters(Collections.singletonMap("First", chapter));

Map<String, AttributeValue> map = table.tableSchema().itemToMap(book, true);
assertNull(map.get("chapter").m().get("text"));

}

@test
public void testBean() throws Exception {
DynamoDbEnhancedClient enhancedClient = getEnhancedClient();
DynamoDbTable table = enhancedClient.table("books", TableSchema.fromBean(Book.class));
table.createTable();

Chapter chapter = new Chapter();
chapter.setPage(1);
Book book = new Book("123");
book.setChapter(chapter);
book.setChapters(Collections.singletonMap("First", chapter));

Map<String, AttributeValue> map = table.tableSchema().itemToMap(book, true);
assertNull(map.get("chapter").m().get("text"));

}

Possible Solution

The ignoreNulls flag is simply not propagated when the conversion is applied. I'm aware it is possible to add DynamoDbIgnoreNulls annotations or explicitly override the EnhancedTypeDocumentConfiguration in static schema construction, but that completely defeats the purpose of having a conversion method with an ignoreNulls parameter.
Calling TableSchema.itemToMap() with ignoreNulls= true should override any statically defined configuration.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugThis issue is a bug.duplicateThis issue is a duplicate.needs-discussionThis issue/PR requires more discussion with community.p3This is a minor priority issue

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions