Fields with underscores work with @DynamoDbBean but not with @DynamoDbImmutable
- Dominant language
- Java
- Stars
- 2.6k
- Forks
- 1k
- Avg merge
- 2d 9h
- Merged PRs (30d)
- 51
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` 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)
Contributor guide
Assessment
This issue has not been assessed yet.