aws-sdk-java-v2 icon indicating copy to clipboard operation
aws-sdk-java-v2 copied to clipboard

DynamoDB enhanced client silently fails when necessary extensions are not installed + exposes no list of installed extensions

Open eliana404 opened this issue 5 months ago • 3 comments

Describe the bug

I learned the hard way that if the VersionedRecordExtension is not installed on my instance of DynamoDbEnhancedClient, the client silently ignores DynamoDbVersionAttribute annotations, stops performing optimistic locking, and writes null versions to the database. There is no compile time or run time check for missing extensions.

Regression Issue

  • [ ] Select this option if this issue appears to be a regression.

Expected Behavior

I expected the client to provide a fast-fail mechanism of some kind if necessary extensions are not installed to support the annotations used in a DynamoDbBean entity definition. At the very least, it would be ideal if the DynamoDbEnhancedClient instances exposed a list of installed extensions so callers could implement their own fast-fail logic.

Current Behavior

The DynamoDbEnhancedClient quietly ignores annotations that are not supported by its list of installed extensions.

Reproduction Steps

The following code snippets can be used to write a record to Dynamo that should have a version field populated with the value 1. Instead, it will have no value for this field.

Entity definition (Kotlin)

@DynamoDbBean
data class MyEntity(
  @get:DynamoDbPartitionKey
  @get:DynamoDbAttribute("pk")
  var pk: String = "",
  // Sort Key, should always be "LOAN" unless we introduce new types of records,
  // which would probably be represented by different classes.
  @get:DynamoDbSortKey
  @get:DynamoDbAttribute("sk")
  var recordType: String = "",

  @get:DynamoDbVersionAttribute
  @get:DynamoDbAttribute("version")
  var version: Int? = null,
)

Client setup (Java):

var client = DynamoDbEnhancedClient.builder()
        .dynamoDbClient(DynamoDbClient.builder().build())
        .extensions(List.of()) // Some list of extensions that causes record versioning extension not to be installed
        .build();

Usage of table (Kotlin):

val table = client.table("my-table", TableSchema.fromBean(MyEntity::class.java))
val record = MyEntity(
  pk = "some-pk",
  sk = "some-sk"
)
table.putItem(PutItemEnhancedRequest.builder(MyEntity::class.java)
  .item(record)
  .build())

Possible Solution

At a minimum, if the enhanced client object could provide a public list of extensions installed, callers could add start-up logic in their applications to assert that expected extensions are there.

Additional Information/Context

No response

AWS Java SDK version used

2.31.54

JDK version used

21.0.4

Operating System and version

MacBook Pro, Apple M2 Max, Sequoia 15.5

eliana404 avatar Jul 02 '25 19:07 eliana404