aws / aws/aws-sdk-java-v2

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

Offen
#5,589 4 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
bug dynamodb-enhanced p2 third-party
Vorherrschende Sprache
Java
Sterne
2.6k
Forks
1k
Ø Merge
2 T. 9 Std.
Gemergte PRs (30 T.)
51

Beschreibung

### 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)

Beitragsleitfaden

Beitragsleitfaden öffnen

Rechercherichtung

Beginne mit der UnderscoreFieldTest-Reproduktion und dem im Stacktrace genannten ImmutableIntrospector-Pfad und verfolge dann, wie TableSchema.fromClass den unveränderlichen Builder verarbeitet. Überprüfe das Verhalten sowohl für @DynamoDbBean als auch für @DynamoDbImmutable und füge einen Regressionstest hinzu oder führe einen solchen aus, der zeigt, dass das unveränderliche Schema für __encryption_keyId erfolgreich aufgelöst wird.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
java
Bereich
databases
Issue-Typ
Bug
Schwierigkeit
3/5
Geschätzter Aufwand
1-2 Tage
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
45/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.