55import static software .amazon .awssdk .enhanced .dynamodb .internal .EnhancedClientUtils .keyRef ;
66import static software .amazon .awssdk .enhanced .dynamodb .internal .EnhancedClientUtils .valueRef ;
77
8+ import java .util .ArrayList ;
89import java .util .Arrays ;
910import java .util .Collections ;
1011import java .util .List ;
3839
3940public class UpdateExpressionTest extends LocalDynamoDbSyncTestBase {
4041
42+ private static final List <String > REQUEST_ATTRIBUTES = new ArrayList <>(Arrays .asList ("attr1" , "attr2" ));
43+
4144 private static final Set <String > SET_ATTRIBUTE_INIT_VALUE = Stream .of ("YELLOW" , "BLUE" , "RED" , "GREEN" )
4245 .collect (Collectors .toSet ());
4346 private static final Set <String > SET_ATTRIBUTE_DELETE = Stream .of ("YELLOW" , "RED" ).collect (Collectors .toSet ());
@@ -68,7 +71,7 @@ public void deleteTable() {
6871 @ Test
6972 public void attribute_notInPojo_notFilteredInExtension_ignoresNulls_updatesNormally () {
7073 initClientWithExtensions (new ItemPreservingUpdateExtension ());
71- RecordForUpdateExpressions record = createRecordWithoutExtensionAttributes ();
74+ RecordForUpdateExpressions record = createFullRecord ();
7275
7376 mappedTable .updateItem (r -> r .item (record ).ignoreNulls (true ));
7477
@@ -91,7 +94,7 @@ public void attribute_notInPojo_notFilteredInExtension_ignoresNulls_updatesNorma
9194 @ Test
9295 public void attribute_notInPojo_notFilteredInExtension_defaultSetsNull_updatesNormally () {
9396 initClientWithExtensions (new ItemPreservingUpdateExtension ());
94- RecordForUpdateExpressions record = createRecordWithoutExtensionAttributes ();
97+ RecordForUpdateExpressions record = createFullRecord ();
9598
9699 mappedTable .updateItem (r -> r .item (record ));
97100
@@ -103,8 +106,7 @@ public void attribute_notInPojo_notFilteredInExtension_defaultSetsNull_updatesNo
103106 @ Test
104107 public void attribute_notInPojo_filteredInExtension_ignoresNulls_updatesNormally () {
105108 initClientWithExtensions (new ItemFilteringUpdateExtension ());
106- RecordForUpdateExpressions record = createRecordWithoutExtensionAttributes ();
107- record .setExtensionSetAttribute (SET_ATTRIBUTE_INIT_VALUE );
109+ RecordForUpdateExpressions record = createFullRecord ();
108110 mappedTable .putItem (record );
109111
110112 record .setStringAttribute ("init" );
@@ -116,8 +118,7 @@ public void attribute_notInPojo_filteredInExtension_ignoresNulls_updatesNormally
116118 @ Test
117119 public void attribute_notInPojo_filteredInExtension_defaultSetsNull_updatesNormally () {
118120 initClientWithExtensions (new ItemFilteringUpdateExtension ());
119- RecordForUpdateExpressions record = createRecordWithoutExtensionAttributes ();
120- record .setExtensionSetAttribute (SET_ATTRIBUTE_INIT_VALUE );
121+ RecordForUpdateExpressions record = createFullRecord ();
121122 mappedTable .putItem (record );
122123
123124 record .setStringAttribute ("init" );
@@ -133,7 +134,7 @@ public void attribute_notInPojo_filteredInExtension_defaultSetsNull_updatesNorma
133134 @ Test
134135 public void attribute_inPojo_notFilteredInExtension_ignoresNulls_ddbError () {
135136 initClientWithExtensions (new ItemPreservingUpdateExtension ());
136- RecordForUpdateExpressions record = createRecordWithoutExtensionAttributes ();
137+ RecordForUpdateExpressions record = createFullRecord ();
137138 record .setExtensionNumberAttribute (100L );
138139
139140 verifyDDBError (record , true );
@@ -142,7 +143,7 @@ public void attribute_inPojo_notFilteredInExtension_ignoresNulls_ddbError() {
142143 @ Test
143144 public void attribute_inPojo_notFilteredInExtension_defaultSetsNull_ddbError () {
144145 initClientWithExtensions (new ItemPreservingUpdateExtension ());
145- RecordForUpdateExpressions record = createRecordWithoutExtensionAttributes ();
146+ RecordForUpdateExpressions record = createFullRecord ();
146147 record .setExtensionNumberAttribute (100L );
147148
148149 verifyDDBError (record , false );
@@ -156,8 +157,7 @@ public void attribute_inPojo_notFilteredInExtension_defaultSetsNull_ddbError() {
156157 @ Test
157158 public void attribute_inPojo_filteredInExtension_ignoresNulls_updatesNormally () {
158159 initClientWithExtensions (new ItemFilteringUpdateExtension ());
159- RecordForUpdateExpressions record = createRecordWithoutExtensionAttributes ();
160- record .setExtensionSetAttribute (SET_ATTRIBUTE_INIT_VALUE );
160+ RecordForUpdateExpressions record = createFullRecord ();
161161 mappedTable .putItem (record );
162162
163163 record .setStringAttribute ("init" );
@@ -170,8 +170,7 @@ public void attribute_inPojo_filteredInExtension_ignoresNulls_updatesNormally()
170170 @ Test
171171 public void attribute_inPojo_filteredInExtension_defaultSetsNull_updatesNormally () {
172172 initClientWithExtensions (new ItemFilteringUpdateExtension ());
173- RecordForUpdateExpressions record = createRecordWithoutExtensionAttributes ();
174- record .setExtensionSetAttribute (SET_ATTRIBUTE_INIT_VALUE );
173+ RecordForUpdateExpressions record = createFullRecord ();
175174 mappedTable .putItem (record );
176175
177176 record .setStringAttribute ("init" );
@@ -184,12 +183,11 @@ public void attribute_inPojo_filteredInExtension_defaultSetsNull_updatesNormally
184183 @ Test
185184 public void chainedExtensions_noDuplicates_ignoresNulls_updatesNormally () {
186185 initClientWithExtensions (new ItemPreservingUpdateExtension (), new ItemFilteringUpdateExtension ());
187- RecordForUpdateExpressions putRecord = createRecordWithoutExtensionAttributes ();
186+ RecordForUpdateExpressions putRecord = createFullRecord ();
188187 putRecord .setExtensionNumberAttribute (11L );
189- putRecord .setExtensionSetAttribute (SET_ATTRIBUTE_INIT_VALUE );
190188 mappedTable .putItem (putRecord );
191189
192- RecordForUpdateExpressions updateRecord = createRecordWithoutExtensionAttributes ();
190+ RecordForUpdateExpressions updateRecord = createFullRecord ();
193191 updateRecord .setStringAttribute ("updated" );
194192 mappedTable .updateItem (r -> r .item (updateRecord ).ignoreNulls (true ));
195193
@@ -202,25 +200,25 @@ public void chainedExtensions_noDuplicates_ignoresNulls_updatesNormally() {
202200 @ Test
203201 public void chainedExtensions_duplicateAttributes_sameValue_sameValueRef_ddbError () {
204202 initClientWithExtensions (new ItemPreservingUpdateExtension (), new ItemPreservingUpdateExtension ());
205- verifyDDBError (createRecordWithoutExtensionAttributes (), false );
203+ verifyDDBError (createFullRecord (), false );
206204 }
207205
208206 @ Test
209207 public void chainedExtensions_duplicateAttributes_sameValue_differentValueRef_ddbError () {
210208 initClientWithExtensions (new ItemPreservingUpdateExtension (), new ItemPreservingUpdateExtension (NUMBER_ATTRIBUTE_VALUE , ":ref" ));
211- verifyDDBError (createRecordWithoutExtensionAttributes (), false );
209+ verifyDDBError (createFullRecord (), false );
212210 }
213211
214212 @ Test
215213 public void chainedExtensions_duplicateAttributes_differentValue_differentValueRef_ddbError () {
216214 initClientWithExtensions (new ItemPreservingUpdateExtension (), new ItemPreservingUpdateExtension (13L , ":ref" ));
217- verifyDDBError (createRecordWithoutExtensionAttributes (), false );
215+ verifyDDBError (createFullRecord (), false );
218216 }
219217
220218 @ Test
221219 public void chainedExtensions_duplicateAttributes_differentValue_sameValueRef_operationMergeError () {
222220 initClientWithExtensions (new ItemPreservingUpdateExtension (), new ItemPreservingUpdateExtension (10L , NUMBER_ATTRIBUTE_VALUE_REF ));
223- RecordForUpdateExpressions record = createRecordWithoutExtensionAttributes ();
221+ RecordForUpdateExpressions record = createFullRecord ();
224222
225223 assertThatThrownBy (() ->mappedTable .updateItem (r -> r .item (record )))
226224 .isInstanceOf (IllegalArgumentException .class )
@@ -231,7 +229,7 @@ public void chainedExtensions_duplicateAttributes_differentValue_sameValueRef_op
231229 @ Test
232230 public void chainedExtensions_duplicateAttributes_invalidValueRef_operationMergeError () {
233231 initClientWithExtensions (new ItemPreservingUpdateExtension (), new ItemPreservingUpdateExtension (10L , "illegal" ));
234- RecordForUpdateExpressions record = createRecordWithoutExtensionAttributes ();
232+ RecordForUpdateExpressions record = createFullRecord ();
235233
236234 assertThatThrownBy (() ->mappedTable .updateItem (r -> r .item (record )))
237235 .isInstanceOf (DynamoDbException .class )
@@ -248,7 +246,7 @@ public void chainedExtensions_duplicateAttributes_invalidValueRef_operationMerge
248246 @ Test
249247 public void updateExpressionInRequest_withoutIgnoreNulls_shouldUpdateSuccessfully () {
250248 initClientWithExtensions ();
251- RecordForUpdateExpressions initialRecord = createRecordWithoutExtensionAttributes ();
249+ RecordForUpdateExpressions initialRecord = createFullRecord ();
252250 putInitialItemAndVerify (initialRecord );
253251
254252 RecordForUpdateExpressions keyRecord = createKeyOnlyRecord ();
@@ -269,7 +267,7 @@ public void updateExpressionInRequest_withoutIgnoreNulls_shouldUpdateSuccessfull
269267 @ Test
270268 public void updateExpressionInRequest_withIgnoreNulls_shouldUpdateSuccessfully () {
271269 initClientWithExtensions ();
272- RecordForUpdateExpressions initialRecord = createRecordWithoutExtensionAttributes ();
270+ RecordForUpdateExpressions initialRecord = createFullRecord ();
273271 putInitialItemAndVerify (initialRecord );
274272
275273 RecordForUpdateExpressions keyRecord = createKeyOnlyRecord ();
@@ -289,7 +287,7 @@ public void updateExpressionInRequest_withIgnoreNulls_shouldUpdateSuccessfully()
289287 @ Test
290288 public void updateExpressionInRequest_whenAttributeAlsoInPojo_shouldThrowConflictError () {
291289 initClientWithExtensions ();
292- RecordForUpdateExpressions initialRecord = createRecordWithoutExtensionAttributes ();
290+ RecordForUpdateExpressions initialRecord = createFullRecord ();
293291 putInitialItemAndVerify (initialRecord );
294292
295293 RecordForUpdateExpressions updateRecord = createKeyOnlyRecord ();
@@ -307,7 +305,7 @@ public void updateExpressionInRequest_whenAttributeAlsoInPojo_shouldThrowConflic
307305 @ Test
308306 public void updateExpressionInRequest_whenAttributeAlsoInExtension_shouldThrowDynamoDbError () {
309307 initClientWithExtensions (new ItemPreservingUpdateExtension ());
310- RecordForUpdateExpressions recordForUpdateExpressions = createRecordWithoutExtensionAttributes ();
308+ RecordForUpdateExpressions recordForUpdateExpressions = createFullRecord ();
311309 assertThatThrownBy (() -> mappedTable .updateItem (r -> r .item (recordForUpdateExpressions )
312310 .updateExpression (expressionWithSetExtensionAttribute ())))
313311 .isInstanceOf (DynamoDbException .class )
@@ -359,9 +357,9 @@ public void backwardCompatibility_extensionOnlyUpdates() {
359357 @ Test
360358 public void scanOperation_afterUpdateExpression () {
361359 initClientWithExtensions ();
362- RecordForUpdateExpressions record1 = createRecordWithoutExtensionAttributes ();
360+ RecordForUpdateExpressions record1 = createFullRecord ();
363361 record1 .setId ("scan1" );
364- RecordForUpdateExpressions record2 = createRecordWithoutExtensionAttributes ();
362+ RecordForUpdateExpressions record2 = createFullRecord ();
365363 record2 .setId ("scan2" );
366364
367365 mappedTable .putItem (record1 );
@@ -391,7 +389,7 @@ public void scanOperation_afterUpdateExpression() {
391389 @ Test
392390 public void deleteItem_afterUpdateExpression () {
393391 initClientWithExtensions ();
394- RecordForUpdateExpressions record = createRecordWithoutExtensionAttributes ();
392+ RecordForUpdateExpressions record = createFullRecord ();
395393 mappedTable .putItem (record );
396394
397395 // Update with expression using key-only record to avoid path conflicts
@@ -422,9 +420,9 @@ public void batchGetItem_afterUpdateExpression() {
422420 .dynamoDbClient (getDynamoDbClient ())
423421 .build ();
424422
425- RecordForUpdateExpressions record1 = createRecordWithoutExtensionAttributes ();
423+ RecordForUpdateExpressions record1 = createFullRecord ();
426424 record1 .setId ("batch1" );
427- RecordForUpdateExpressions record2 = createRecordWithoutExtensionAttributes ();
425+ RecordForUpdateExpressions record2 = createFullRecord ();
428426 record2 .setId ("batch2" );
429427
430428 mappedTable .putItem (record1 );
@@ -467,9 +465,9 @@ public void batchWriteItem_withUpdateExpressionItems() {
467465 .dynamoDbClient (getDynamoDbClient ())
468466 .build ();
469467
470- RecordForUpdateExpressions record1 = createRecordWithoutExtensionAttributes ();
468+ RecordForUpdateExpressions record1 = createFullRecord ();
471469 record1 .setId ("batchWrite1" );
472- RecordForUpdateExpressions record2 = createRecordWithoutExtensionAttributes ();
470+ RecordForUpdateExpressions record2 = createFullRecord ();
473471 record2 .setId ("batchWrite2" );
474472
475473 // First update with expressions using key-only record to avoid path conflicts
@@ -505,9 +503,9 @@ public void transactGetItems_afterUpdateExpression() {
505503 .dynamoDbClient (getDynamoDbClient ())
506504 .build ();
507505
508- RecordForUpdateExpressions record1 = createRecordWithoutExtensionAttributes ();
506+ RecordForUpdateExpressions record1 = createFullRecord ();
509507 record1 .setId ("transact1" );
510- RecordForUpdateExpressions record2 = createRecordWithoutExtensionAttributes ();
508+ RecordForUpdateExpressions record2 = createFullRecord ();
511509 record2 .setId ("transact2" );
512510
513511 mappedTable .putItem (record1 );
@@ -548,9 +546,9 @@ public void transactWriteItems_withUpdateExpression() {
548546 .dynamoDbClient (getDynamoDbClient ())
549547 .build ();
550548
551- RecordForUpdateExpressions record1 = createRecordWithoutExtensionAttributes ();
549+ RecordForUpdateExpressions record1 = createFullRecord ();
552550 record1 .setId ("transactWrite1" );
553- RecordForUpdateExpressions record2 = createRecordWithoutExtensionAttributes ();
551+ RecordForUpdateExpressions record2 = createFullRecord ();
554552 record2 .setId ("transactWrite2" );
555553
556554 mappedTable .putItem (record1 );
@@ -586,32 +584,35 @@ private void verifySetAttribute(RecordForUpdateExpressions record) {
586584 assertThat (persistedRecord .getExtensionSetAttribute ()).isEqualTo (expectedAttribute );
587585 }
588586
589- private RecordForUpdateExpressions createRecordWithoutExtensionAttributes () {
587+ /** Creates record with only the partition key (id) */
588+ private RecordForUpdateExpressions createKeyOnlyRecord () {
590589 RecordForUpdateExpressions record = new RecordForUpdateExpressions ();
591590 record .setId ("1" );
592- record .setStringAttribute ("init" );
593- record .setRequestAttributeList (Arrays .asList ("attr1" , "attr2" ));
594591 return record ;
595592 }
596593
594+ /** Creates record with POJO attributes (id + stringAttribute) */
597595 private RecordForUpdateExpressions createSimpleRecord () {
598596 RecordForUpdateExpressions record = new RecordForUpdateExpressions ();
599597 record .setId ("1" );
600598 record .setStringAttribute ("init" );
601599 return record ;
602600 }
603601
604- private RecordForUpdateExpressions createKeyOnlyRecord () {
605- RecordForUpdateExpressions record = new RecordForUpdateExpressions ();
606- record .setId ("1" );
602+ /** Creates record with POJO + extension + request attributes (requestAttributeList for request UpdateExpressions,
603+ * extensionSetAttribute for extension UpdateExpressions) */
604+ private RecordForUpdateExpressions createFullRecord () {
605+ RecordForUpdateExpressions record = createSimpleRecord ();
606+ record .setRequestAttributeList (new ArrayList <>(REQUEST_ATTRIBUTES ));
607+ record .setExtensionSetAttribute (SET_ATTRIBUTE_INIT_VALUE );
607608 return record ;
608609 }
609610
610611 private void putInitialItemAndVerify (RecordForUpdateExpressions record ) {
611612 mappedTable .putItem (r -> r .item (record ));
612613 RecordForUpdateExpressions persistedRecord = mappedTable .getItem (record );
613614 List <String > requestAttributeList = persistedRecord .getRequestAttributeList ();
614- assertThat (requestAttributeList ).hasSize (2 ).isEqualTo (Arrays . asList ( "attr1" , "attr2" ) );
615+ assertThat (requestAttributeList ).hasSize (2 ).isEqualTo (REQUEST_ATTRIBUTES );
615616 }
616617
617618 private UpdateExpression expressionWithSetListElement (int index , String value ) {
0 commit comments