Skip to content

Fields with underscores work with @DynamoDbBean but not with @DynamoDbImmutable #5589

Open
@klach-ocado

Description

@klach-ocado

Describe the bug

It is possible to declare a DynamoDB entity class with such a field:

private String __encryption_keyId;

... and use the entity when it's annotated @DynamoDbBean but it's not possible when it's annotated @DynamoDbImmutable.

Expected Behavior

Consistent behavior for both @DynamoDbBean and @DynamoDbImmutable annotations. As it's already working for @DynamoDbBean, it should work for @DynamoDbImmutable too, rather than copying a restriction from @DynamoDbImmutable to @DynamoDbBean.

Current Behavior

TableSchema.fromClass(...) throws an exception:

java.lang.IllegalArgumentException: A method was found on the immutable class that does not appear to have a matching setter on the builder class. Use the @DynamoDbIgnore annotation on the method if you do not want it to be included in the TableSchema introspection. [Method = "public java.lang.String com.example.UnderscoreFieldTest$Immutable.get__encryption_keyId()"]
	at software.amazon.awssdk.enhanced.dynamodb.internal.immutable.ImmutableIntrospector.generateExceptionForMethod(ImmutableIntrospector.java:134)
	at software.amazon.awssdk.enhanced.dynamodb.internal.immutable.ImmutableIntrospector.lambda$introspect$1(ImmutableIntrospector.java:87)
	at java.base/java.util.Optional.orElseThrow(Optional.java:403)
	at software.amazon.awssdk.enhanced.dynamodb.internal.immutable.ImmutableIntrospector.lambda$introspect$2(ImmutableIntrospector.java:86)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
	at software.amazon.awssdk.enhanced.dynamodb.internal.immutable.ImmutableIntrospector.introspect(ImmutableIntrospector.java:93)
	at software.amazon.awssdk.enhanced.dynamodb.internal.immutable.ImmutableIntrospector.getImmutableInfo(ImmutableIntrospector.java:65)
	at software.amazon.awssdk.enhanced.dynamodb.mapper.ImmutableTableSchema.createStaticImmutableTableSchema(ImmutableTableSchema.java:174)
	at software.amazon.awssdk.enhanced.dynamodb.mapper.ImmutableTableSchema.create(ImmutableTableSchema.java:145)
	at software.amazon.awssdk.enhanced.dynamodb.mapper.ImmutableTableSchema.lambda$create$0(ImmutableTableSchema.java:134)
	at java.base/java.util.Map.computeIfAbsent(Map.java:1054)
	at java.base/java.util.Collections$SynchronizedMap.computeIfAbsent(Collections.java:2760)
	at software.amazon.awssdk.enhanced.dynamodb.mapper.ImmutableTableSchema.create(ImmutableTableSchema.java:133)
	at software.amazon.awssdk.enhanced.dynamodb.TableSchema.fromImmutableClass(TableSchema.java:141)
	at software.amazon.awssdk.enhanced.dynamodb.TableSchema.fromClass(TableSchema.java:164)

Reproduction Steps

Run the test:

package com.example;

import lombok.Builder;
import lombok.Data;
import lombok.Getter;
import lombok.Value;
import org.junit.jupiter.api.Test;
import software.amazon.awssdk.enhanced.dynamodb.TableSchema;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbBean;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbImmutable;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey;

import static org.assertj.core.api.Assertions.assertThatCode;

class UnderscoreFieldTest {

    @Test
    void shouldResolveTableSchemaFromBean() {
        assertThatCode(() -> TableSchema.fromClass(Bean.class)).doesNotThrowAnyException();
    }

    @Test
    void shouldResolveTableSchemaFromImmutable() {
        assertThatCode(() -> TableSchema.fromClass(Immutable.class)).doesNotThrowAnyException();
    }

    @Data
    @DynamoDbBean
    public static class Bean {

        @Getter(onMethod_ = @DynamoDbPartitionKey)
        private String id;

        private String __encryption_keyId;
    }

    @Value
    @Builder
    @DynamoDbImmutable(builder = Immutable.ImmutableBuilder.class)
    public static class Immutable {

        @Getter(onMethod_ = @DynamoDbPartitionKey)
        private String id;

        private String __encryption_keyId;
    }
}

Dependencies:

  • software.amazon.awssdk:dynamodb-enhanced version 2.27.19
  • org.springframework.boot:spring-boot-starter-test version 3.3.3
  • org.projectlombok:lombok version 1.18.34

Possible Solution

Release restrictions for @DynamoDbImmutable annotation.

Additional Information/Context

No response

AWS Java SDK version used

2.27.19

JDK version used

openjdk version "17.0.3" 2022-04-19

Operating System and version

multiple (macOS 14.6.1, Ubuntu Linux 22.04 LTS)

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions