Skip to content

Conversation

anasatirbasa
Copy link

@anasatirbasa anasatirbasa commented Aug 26, 2025

Description

Added the facility of using an annotation that will auto-generate a key for an attribute in a class,
similar to the legacy V1 @DynamoDBAutoGeneratedKey, now ported and adapted for V2 with the Enhanced Client.

Important Restriction

This annotation is only valid for primary keys (PK/SK) or secondary index keys (GSI/LSI PK/SK).
If applied to a non-key attribute, the extension will throw an IllegalArgumentException.

If the attribute is not provided by the client, the SDK will automatically generate a value (UUID by default)
during serialization. If the attribute already has a value, it will be preserved depending on the update policy applied.
The implementation reuses the concept from V1 but leverages the V2 Enhanced Client extension model to achieve parity.

A key aspect of this feature is its combination with @DynamoDbUpdateBehavior. This determines whether a generated key is one-time only or is regenerated on every update:

  • Default (WRITE_ALWAYS) → The attribute will be regenerated on every write if missing, even during updates. Useful for attributes like lastUpdatedKey that are meant to refresh often.
  • WRITE_IF_NOT_EXISTS → The attribute will only be generated once (on the first insert) and preserved across updates. This is the recommended option for stable identifiers like createdKey.

Motivation and Context

#5497

This functionality was present in V1 under @DynamoDBAutoGeneratedKey. Many users requested its reintroduction in V2.
By introducing this annotation and the supporting extension, we align the Enhanced Client API with developer expectations and provide a familiar migration path.

Modifications

  • Added the new annotation @DynamoDbAutoGeneratedKey in the software.amazon.awssdk.enhanced.dynamodb.extensions.annotations package.
  • Introduced AutoGeneratedKeyExtension, which ensures attributes annotated with @DynamoDbAutoGeneratedKey are populated with a UUID when absent. This uses UUID.randomUUID() under the hood.
  • Added AutoGeneratedKeyTag as the annotation tag integration point.
  • Integrated with @DynamoDbUpdateBehavior to support both stable one-time keys (WRITE_IF_NOT_EXISTS) and regenerating keys (WRITE_ALWAYS).
  • Validated attribute type constraints (only String is supported).
  • Enforced placement rules (only PK/SK, LSI/GSI keys are allowed).
  • Added corresponding unit tests (AutoGeneratedKeyExtensionTest) and functional integration tests (AutoGeneratedKeyRecordTest) to verify correct behavior with real DynamoDB operations.
  • Tests validate multiple scenarios, including updates, conditional writes, composite annotations,
    and integration with VersionedRecordExtension.

Testing

The changes have already been tested by running the existing tests and also added new unit/integration tests
for the new flow, ensuring parity with V1 behavior while also validating V2-specific integration points.

Test Coverage Checklist

Scenario Done Comments if Not Done
1. Different TableSchema Creation Methods
a. TableSchema.fromBean(Customer.class) [x]
b. TableSchema.fromImmutableClass(Customer.class) for immutable classes [x]
c. TableSchema.documentSchemaBuilder().build() [ ]
d. StaticTableSchema.builder(Customer.class) [x]
2. Nesting of Different TableSchema Types
a. @DynamoDbBean with annotated auto-generated key [x]
b. @DynamoDbImmutable with annotated auto-generated key [x]
c. Auto-generated key combined with partition/sort key [x]
3. CRUD Operations
a. scan() [ ]
b. query() [x]
c. updateItem() preserves existing value or generates when absent [x]
d. putItem() with no key set (auto-generation occurs) [x]
e. putItem() with key set manually [x]
f. getItem() retrieves auto-generated key [x]
g. deleteItem() [ ]
h. batchGetItem() [ ]
i. batchWriteItem() [ ]
j. transactGetItems() [ ]
k. transactWriteItems() [ ]
4. Data Types and Null Handling
a. Annotated attribute is null → key auto-generated [x]
b. Annotated attribute non-null → value preserved [x]
c. Validation rejects non-String annotated attribute [x]
5. AsyncTable and SyncTable
a. DynamoDbAsyncTable Testing [x]
b. DynamoDbTable Testing [x]
6. New/Modification in Extensions
a. Works with other extensions like VersionedRecordExtension [x]
b. Test with Default Values in Annotations [ ]
c. Combination of Annotation and Builder passes extension [ ]
7. New/Modification in Converters
a. Tables with Scenario in ScenarioSl No.1 (All table schemas are Must) [ ]
b. Test with Default Values in Annotations [ ]
c. Test All Scenarios from 1 to 5 [ ]

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)

Checklist

  • I have read the CONTRIBUTING document
  • Local run of mvn install succeeds
  • My code follows the code style of this project
  • My change requires a change to the Javadoc documentation
  • I have updated the Javadoc documentation accordingly
  • I have added tests to cover my changes
  • All new and existing tests passed
  • I have added a changelog entry. Adding a new entry must be accomplished by running the scripts/new-change script and following the instructions. Commit the new file created by the script in .changes/next-release with your changes.
  • My change is to implement 1.11 parity feature and I have updated LaunchChangelog

License

  • I confirm that this pull request can be released under the Apache 2 license

@anasatirbasa anasatirbasa requested a review from a team as a code owner August 26, 2025 06:36
@anasatirbasa anasatirbasa force-pushed the feature/define-dynamo-db-autogenerated-key-annotation branch 2 times, most recently from 519acfe to fa35bfc Compare August 26, 2025 11:31
@anasatirbasa anasatirbasa force-pushed the feature/define-dynamo-db-autogenerated-key-annotation branch from 586dbf5 to 1c0b19f Compare August 27, 2025 17:07
@anasatirbasa anasatirbasa reopened this Aug 27, 2025
@anasatirbasa anasatirbasa force-pushed the feature/define-dynamo-db-autogenerated-key-annotation branch 3 times, most recently from 6c310a6 to 335e532 Compare August 28, 2025 06:18
… - ConditionalCheckFailedException with version attribute and partition key using auto-generated UUID]
@anasatirbasa anasatirbasa force-pushed the feature/define-dynamo-db-autogenerated-key-annotation branch from 335e532 to f3a3ad1 Compare August 28, 2025 06:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant