Skip to content

Conversation

anasatirbasa
Copy link

@anasatirbasa anasatirbasa commented Sep 3, 2025

Description

Fixed the behavior of the @DynamoDbAutoGeneratedUuid annotation in combination with
@DynamoDbUpdateBehavior(UpdateBehavior.WRITE_IF_NOT_EXISTS).

Previously, a new UUID was generated even when the attribute already had a value. With this change:

  • If the attribute is missing or empty, the extension generates a UUID (via UUID.randomUUID()).
  • If the attribute already has a non-empty value, it is preserved and not overwritten.
  • On updates with WRITE_IF_NOT_EXISTS, existing values in DynamoDB are preserved using the if_not_exists(...) expression.

This ensures that UUIDs are only generated once for attributes tagged with WRITE_IF_NOT_EXISTS and remain stable across subsequent updates.

Important Note

  • The annotation can be applied to any String attribute.
  • Unlike @DynamoDbAutoGeneratedKey (implementation added with this PR) , this extension does not enforce PK/SK or index-only usage — it supports non-key attributes.
  • On putItem, the entire item is always replaced, so if the field is absent, a new UUID will still be generated, even with WRITE_IF_NOT_EXISTS.

Motivation and Context

#5703

This bug fix improves consistency with the documented semantics of WRITE_IF_NOT_EXISTS and matches user expectations.

Modifications

  • Updated AutoGeneratedUuidExtension to only generate UUIDs if the attribute is missing or empty.
  • Preserved existing values when present in the item map.
  • Adjusted Javadoc to reflect correct semantics for WRITE_IF_NOT_EXISTS.
  • Added unit tests in AutoGeneratedUuidExtensionTest and functional tests in AutoGeneratedUuidRecordTest to verify:
    • UUID is generated when missing.
    • UUID is preserved when already present.
    • Correct interaction with WRITE_ALWAYS vs. WRITE_IF_NOT_EXISTS.

Testing

  • Verified with existing unit tests.
  • Added new tests to ensure existing values are preserved.
  • Confirmed expected behavior with both putItem and updateItem.

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 September 3, 2025 11:18
@anasatirbasa anasatirbasa force-pushed the feature/fix-handling-of-write-if-not-exists-on-dynamo-db-autogenerated-uuid-annotation branch 4 times, most recently from c07ff14 to baee3b7 Compare September 5, 2025 07:09
@anasatirbasa anasatirbasa force-pushed the feature/fix-handling-of-write-if-not-exists-on-dynamo-db-autogenerated-uuid-annotation branch from ad40026 to 91a13ce Compare September 5, 2025 07:12
…s-on-dynamo-db-autogenerated-uuid-annotation
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