Open
Description
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
version2.27.19
org.springframework.boot:spring-boot-starter-test
version3.3.3
org.projectlombok:lombok
version1.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)