Search in sources :

Example 1 with WriteModification

use of software.amazon.awssdk.enhanced.dynamodb.extensions.WriteModification in project aws-sdk-java-v2 by aws.

the class UpdateItemOperation method addExpressionsIfExist.

private UpdateItemRequest.Builder addExpressionsIfExist(WriteModification transformation, Map<String, AttributeValue> filteredAttributeValues, UpdateItemRequest.Builder requestBuilder, TableMetadata tableMetadata) {
    Map<String, String> expressionNames = null;
    Map<String, AttributeValue> expressionValues = null;
    String conditionExpressionString = null;
    /* Add update expression for transformed non-key attributes if applicable */
    if (!filteredAttributeValues.isEmpty()) {
        Expression fullUpdateExpression = generateUpdateExpression(filteredAttributeValues, tableMetadata);
        expressionNames = fullUpdateExpression.expressionNames();
        expressionValues = fullUpdateExpression.expressionValues();
        requestBuilder = requestBuilder.updateExpression(fullUpdateExpression.expression());
    }
    /* Merge in conditional expression from extension WriteModification if applicable */
    if (transformation != null && transformation.additionalConditionalExpression() != null) {
        expressionNames = Expression.joinNames(expressionNames, transformation.additionalConditionalExpression().expressionNames());
        expressionValues = Expression.joinValues(expressionValues, transformation.additionalConditionalExpression().expressionValues());
        conditionExpressionString = transformation.additionalConditionalExpression().expression();
    }
    /* Merge in conditional expression from specified 'conditionExpression' if applicable */
    Expression conditionExpression = request.map(r -> Optional.ofNullable(r.conditionExpression()), r -> Optional.ofNullable(r.conditionExpression())).orElse(null);
    if (conditionExpression != null) {
        expressionNames = Expression.joinNames(expressionNames, conditionExpression.expressionNames());
        expressionValues = Expression.joinValues(expressionValues, conditionExpression.expressionValues());
        conditionExpressionString = Expression.joinExpressions(conditionExpressionString, conditionExpression.expression(), " AND ");
    }
    // Avoiding adding empty collections that the low level SDK will propagate to DynamoDb where it causes error.
    if (expressionNames != null && !expressionNames.isEmpty()) {
        requestBuilder = requestBuilder.expressionAttributeNames(expressionNames);
    }
    if (expressionValues != null && !expressionValues.isEmpty()) {
        requestBuilder = requestBuilder.expressionAttributeValues(expressionValues);
    }
    return requestBuilder.conditionExpression(conditionExpressionString);
}
Also used : TransactWriteItem(software.amazon.awssdk.services.dynamodb.model.TransactWriteItem) UpdateItemRequest(software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest) DynamoDbAsyncClient(software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient) TransactUpdateItemEnhancedRequest(software.amazon.awssdk.enhanced.dynamodb.model.TransactUpdateItemEnhancedRequest) CompletableFuture(java.util.concurrent.CompletableFuture) Expression(software.amazon.awssdk.enhanced.dynamodb.Expression) Function(java.util.function.Function) Update(software.amazon.awssdk.services.dynamodb.model.Update) UpdateBehaviorTag(software.amazon.awssdk.enhanced.dynamodb.internal.mapper.UpdateBehaviorTag) ArrayList(java.util.ArrayList) Map(java.util.Map) EnhancedClientUtils.isNullAttributeValue(software.amazon.awssdk.enhanced.dynamodb.internal.EnhancedClientUtils.isNullAttributeValue) EnhancedClientUtils(software.amazon.awssdk.enhanced.dynamodb.internal.EnhancedClientUtils) DynamoDbClient(software.amazon.awssdk.services.dynamodb.DynamoDbClient) UpdateBehavior(software.amazon.awssdk.enhanced.dynamodb.mapper.UpdateBehavior) EnhancedClientUtils.readAndTransformSingleItem(software.amazon.awssdk.enhanced.dynamodb.internal.EnhancedClientUtils.readAndTransformSingleItem) Collection(java.util.Collection) TableSchema(software.amazon.awssdk.enhanced.dynamodb.TableSchema) WriteModification(software.amazon.awssdk.enhanced.dynamodb.extensions.WriteModification) Either(software.amazon.awssdk.utils.Either) Collectors(java.util.stream.Collectors) UpdateItemEnhancedRequest(software.amazon.awssdk.enhanced.dynamodb.model.UpdateItemEnhancedRequest) DefaultDynamoDbExtensionContext(software.amazon.awssdk.enhanced.dynamodb.internal.extensions.DefaultDynamoDbExtensionContext) List(java.util.List) DynamoDbEnhancedClientExtension(software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClientExtension) TableMetadata(software.amazon.awssdk.enhanced.dynamodb.TableMetadata) UpdateItemEnhancedResponse(software.amazon.awssdk.enhanced.dynamodb.model.UpdateItemEnhancedResponse) OperationContext(software.amazon.awssdk.enhanced.dynamodb.OperationContext) AttributeValue(software.amazon.awssdk.services.dynamodb.model.AttributeValue) Optional(java.util.Optional) SdkInternalApi(software.amazon.awssdk.annotations.SdkInternalApi) Collections(java.util.Collections) ReturnValue(software.amazon.awssdk.services.dynamodb.model.ReturnValue) UpdateItemResponse(software.amazon.awssdk.services.dynamodb.model.UpdateItemResponse) EnhancedClientUtils.isNullAttributeValue(software.amazon.awssdk.enhanced.dynamodb.internal.EnhancedClientUtils.isNullAttributeValue) AttributeValue(software.amazon.awssdk.services.dynamodb.model.AttributeValue) Expression(software.amazon.awssdk.enhanced.dynamodb.Expression)

Example 2 with WriteModification

use of software.amazon.awssdk.enhanced.dynamodb.extensions.WriteModification in project aws-sdk-java-v2 by aws.

the class UpdateItemOperation method generateConditionExpressionIfExist.

/**
 * Retrieves the ConditionExpression from extensions if existing, and retrieves the ConditionExpression from the request
 * if existing. If both exist, they are merged.
 */
private Expression generateConditionExpressionIfExist(WriteModification transformation, Either<UpdateItemEnhancedRequest<T>, TransactUpdateItemEnhancedRequest<T>> request) {
    Expression conditionExpression = null;
    if (transformation != null && transformation.additionalConditionalExpression() != null) {
        conditionExpression = transformation.additionalConditionalExpression();
    }
    Expression operationConditionExpression = request.map(r -> Optional.ofNullable(r.conditionExpression()), r -> Optional.ofNullable(r.conditionExpression())).orElse(null);
    if (operationConditionExpression != null) {
        conditionExpression = operationConditionExpression.and(conditionExpression);
    }
    return conditionExpression;
}
Also used : TransactWriteItem(software.amazon.awssdk.services.dynamodb.model.TransactWriteItem) UpdateItemRequest(software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest) DynamoDbAsyncClient(software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient) TransactUpdateItemEnhancedRequest(software.amazon.awssdk.enhanced.dynamodb.model.TransactUpdateItemEnhancedRequest) CompletableFuture(java.util.concurrent.CompletableFuture) Expression(software.amazon.awssdk.enhanced.dynamodb.Expression) Function(java.util.function.Function) Update(software.amazon.awssdk.services.dynamodb.model.Update) UpdateExpression(software.amazon.awssdk.enhanced.dynamodb.update.UpdateExpression) CollectionUtils(software.amazon.awssdk.utils.CollectionUtils) Map(java.util.Map) CollectionUtils.filterMap(software.amazon.awssdk.utils.CollectionUtils.filterMap) UpdateExpressionConverter(software.amazon.awssdk.enhanced.dynamodb.internal.update.UpdateExpressionConverter) UpdateExpressionUtils.operationExpression(software.amazon.awssdk.enhanced.dynamodb.internal.update.UpdateExpressionUtils.operationExpression) DynamoDbClient(software.amazon.awssdk.services.dynamodb.DynamoDbClient) EnhancedClientUtils.readAndTransformSingleItem(software.amazon.awssdk.enhanced.dynamodb.internal.EnhancedClientUtils.readAndTransformSingleItem) Collection(java.util.Collection) TableSchema(software.amazon.awssdk.enhanced.dynamodb.TableSchema) WriteModification(software.amazon.awssdk.enhanced.dynamodb.extensions.WriteModification) Either(software.amazon.awssdk.utils.Either) UpdateItemEnhancedRequest(software.amazon.awssdk.enhanced.dynamodb.model.UpdateItemEnhancedRequest) DefaultDynamoDbExtensionContext(software.amazon.awssdk.enhanced.dynamodb.internal.extensions.DefaultDynamoDbExtensionContext) List(java.util.List) DynamoDbEnhancedClientExtension(software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClientExtension) TableMetadata(software.amazon.awssdk.enhanced.dynamodb.TableMetadata) UpdateItemEnhancedResponse(software.amazon.awssdk.enhanced.dynamodb.model.UpdateItemEnhancedResponse) OperationContext(software.amazon.awssdk.enhanced.dynamodb.OperationContext) AttributeValue(software.amazon.awssdk.services.dynamodb.model.AttributeValue) Optional(java.util.Optional) SdkInternalApi(software.amazon.awssdk.annotations.SdkInternalApi) ReturnValue(software.amazon.awssdk.services.dynamodb.model.ReturnValue) UpdateItemResponse(software.amazon.awssdk.services.dynamodb.model.UpdateItemResponse) Expression(software.amazon.awssdk.enhanced.dynamodb.Expression) UpdateExpression(software.amazon.awssdk.enhanced.dynamodb.update.UpdateExpression) UpdateExpressionUtils.operationExpression(software.amazon.awssdk.enhanced.dynamodb.internal.update.UpdateExpressionUtils.operationExpression)

Example 3 with WriteModification

use of software.amazon.awssdk.enhanced.dynamodb.extensions.WriteModification in project aws-sdk-java-v2 by aws.

the class PutItemOperation method generateRequest.

@Override
public PutItemRequest generateRequest(TableSchema<T> tableSchema, OperationContext operationContext, DynamoDbEnhancedClientExtension extension) {
    if (!TableMetadata.primaryIndexName().equals(operationContext.indexName())) {
        throw new IllegalArgumentException("PutItem cannot be executed against a secondary index.");
    }
    TableMetadata tableMetadata = tableSchema.tableMetadata();
    // Fail fast if required primary partition key does not exist and avoid the call to DynamoDb
    tableMetadata.primaryPartitionKey();
    boolean alwaysIgnoreNulls = true;
    T item = request.map(PutItemEnhancedRequest::item, TransactPutItemEnhancedRequest::item);
    Map<String, AttributeValue> itemMap = tableSchema.itemToMap(item, alwaysIgnoreNulls);
    WriteModification transformation = extension != null ? extension.beforeWrite(DefaultDynamoDbExtensionContext.builder().items(itemMap).operationContext(operationContext).tableMetadata(tableMetadata).tableSchema(tableSchema).operationName(operationName()).build()) : null;
    if (transformation != null && transformation.transformedItem() != null) {
        itemMap = transformation.transformedItem();
    }
    PutItemRequest.Builder requestBuilder = PutItemRequest.builder().tableName(operationContext.tableName()).item(itemMap);
    if (request.left().isPresent()) {
        requestBuilder = addPlainPutItemParameters(requestBuilder, request.left().get());
    }
    requestBuilder = addExpressionsIfExist(requestBuilder, transformation);
    return requestBuilder.build();
}
Also used : TableMetadata(software.amazon.awssdk.enhanced.dynamodb.TableMetadata) TransactPutItemEnhancedRequest(software.amazon.awssdk.enhanced.dynamodb.model.TransactPutItemEnhancedRequest) WriteModification(software.amazon.awssdk.enhanced.dynamodb.extensions.WriteModification) AttributeValue(software.amazon.awssdk.services.dynamodb.model.AttributeValue) PutItemRequest(software.amazon.awssdk.services.dynamodb.model.PutItemRequest) PutItemEnhancedRequest(software.amazon.awssdk.enhanced.dynamodb.model.PutItemEnhancedRequest) TransactPutItemEnhancedRequest(software.amazon.awssdk.enhanced.dynamodb.model.TransactPutItemEnhancedRequest)

Example 4 with WriteModification

use of software.amazon.awssdk.enhanced.dynamodb.extensions.WriteModification in project aws-sdk-java-v2 by aws.

the class UpdateItemOperation method generateRequest.

@Override
public UpdateItemRequest generateRequest(TableSchema<T> tableSchema, OperationContext operationContext, DynamoDbEnhancedClientExtension extension) {
    if (!TableMetadata.primaryIndexName().equals(operationContext.indexName())) {
        throw new IllegalArgumentException("UpdateItem cannot be executed against a secondary index.");
    }
    T item = request.map(UpdateItemEnhancedRequest::item, TransactUpdateItemEnhancedRequest::item);
    Boolean ignoreNulls = request.map(r -> Optional.ofNullable(r.ignoreNulls()), r -> Optional.ofNullable(r.ignoreNulls())).orElse(null);
    Map<String, AttributeValue> itemMap = tableSchema.itemToMap(item, Boolean.TRUE.equals(ignoreNulls));
    TableMetadata tableMetadata = tableSchema.tableMetadata();
    WriteModification transformation = extension != null ? extension.beforeWrite(DefaultDynamoDbExtensionContext.builder().items(itemMap).operationContext(operationContext).tableMetadata(tableMetadata).tableSchema(tableSchema).operationName(operationName()).build()) : null;
    if (transformation != null && transformation.transformedItem() != null) {
        itemMap = transformation.transformedItem();
    }
    Collection<String> primaryKeys = tableSchema.tableMetadata().primaryKeys();
    Map<String, AttributeValue> keyAttributes = filterMap(itemMap, entry -> primaryKeys.contains(entry.getKey()));
    Map<String, AttributeValue> nonKeyAttributes = filterMap(itemMap, entry -> !primaryKeys.contains(entry.getKey()));
    Expression updateExpression = generateUpdateExpressionIfExist(tableMetadata, transformation, nonKeyAttributes);
    Expression conditionExpression = generateConditionExpressionIfExist(transformation, request);
    Map<String, String> expressionNames = coalesceExpressionNames(updateExpression, conditionExpression);
    Map<String, AttributeValue> expressionValues = coalesceExpressionValues(updateExpression, conditionExpression);
    UpdateItemRequest.Builder requestBuilder = UpdateItemRequest.builder().tableName(operationContext.tableName()).key(keyAttributes).returnValues(ReturnValue.ALL_NEW);
    if (request.left().isPresent()) {
        addPlainUpdateItemParameters(requestBuilder, request.left().get());
    }
    if (updateExpression != null) {
        requestBuilder.updateExpression(updateExpression.expression());
    }
    if (conditionExpression != null) {
        requestBuilder.conditionExpression(conditionExpression.expression());
    }
    if (CollectionUtils.isNotEmpty(expressionNames)) {
        requestBuilder = requestBuilder.expressionAttributeNames(expressionNames);
    }
    if (CollectionUtils.isNotEmpty(expressionValues)) {
        requestBuilder = requestBuilder.expressionAttributeValues(expressionValues);
    }
    return requestBuilder.build();
}
Also used : TransactWriteItem(software.amazon.awssdk.services.dynamodb.model.TransactWriteItem) UpdateItemRequest(software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest) DynamoDbAsyncClient(software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient) TransactUpdateItemEnhancedRequest(software.amazon.awssdk.enhanced.dynamodb.model.TransactUpdateItemEnhancedRequest) CompletableFuture(java.util.concurrent.CompletableFuture) Expression(software.amazon.awssdk.enhanced.dynamodb.Expression) Function(java.util.function.Function) Update(software.amazon.awssdk.services.dynamodb.model.Update) UpdateExpression(software.amazon.awssdk.enhanced.dynamodb.update.UpdateExpression) CollectionUtils(software.amazon.awssdk.utils.CollectionUtils) Map(java.util.Map) CollectionUtils.filterMap(software.amazon.awssdk.utils.CollectionUtils.filterMap) UpdateExpressionConverter(software.amazon.awssdk.enhanced.dynamodb.internal.update.UpdateExpressionConverter) UpdateExpressionUtils.operationExpression(software.amazon.awssdk.enhanced.dynamodb.internal.update.UpdateExpressionUtils.operationExpression) DynamoDbClient(software.amazon.awssdk.services.dynamodb.DynamoDbClient) EnhancedClientUtils.readAndTransformSingleItem(software.amazon.awssdk.enhanced.dynamodb.internal.EnhancedClientUtils.readAndTransformSingleItem) Collection(java.util.Collection) TableSchema(software.amazon.awssdk.enhanced.dynamodb.TableSchema) WriteModification(software.amazon.awssdk.enhanced.dynamodb.extensions.WriteModification) Either(software.amazon.awssdk.utils.Either) UpdateItemEnhancedRequest(software.amazon.awssdk.enhanced.dynamodb.model.UpdateItemEnhancedRequest) DefaultDynamoDbExtensionContext(software.amazon.awssdk.enhanced.dynamodb.internal.extensions.DefaultDynamoDbExtensionContext) List(java.util.List) DynamoDbEnhancedClientExtension(software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClientExtension) TableMetadata(software.amazon.awssdk.enhanced.dynamodb.TableMetadata) UpdateItemEnhancedResponse(software.amazon.awssdk.enhanced.dynamodb.model.UpdateItemEnhancedResponse) OperationContext(software.amazon.awssdk.enhanced.dynamodb.OperationContext) AttributeValue(software.amazon.awssdk.services.dynamodb.model.AttributeValue) Optional(java.util.Optional) SdkInternalApi(software.amazon.awssdk.annotations.SdkInternalApi) ReturnValue(software.amazon.awssdk.services.dynamodb.model.ReturnValue) UpdateItemResponse(software.amazon.awssdk.services.dynamodb.model.UpdateItemResponse) TableMetadata(software.amazon.awssdk.enhanced.dynamodb.TableMetadata) WriteModification(software.amazon.awssdk.enhanced.dynamodb.extensions.WriteModification) TransactUpdateItemEnhancedRequest(software.amazon.awssdk.enhanced.dynamodb.model.TransactUpdateItemEnhancedRequest) UpdateItemEnhancedRequest(software.amazon.awssdk.enhanced.dynamodb.model.UpdateItemEnhancedRequest) AttributeValue(software.amazon.awssdk.services.dynamodb.model.AttributeValue) UpdateItemRequest(software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest) TransactUpdateItemEnhancedRequest(software.amazon.awssdk.enhanced.dynamodb.model.TransactUpdateItemEnhancedRequest) Expression(software.amazon.awssdk.enhanced.dynamodb.Expression) UpdateExpression(software.amazon.awssdk.enhanced.dynamodb.update.UpdateExpression) UpdateExpressionUtils.operationExpression(software.amazon.awssdk.enhanced.dynamodb.internal.update.UpdateExpressionUtils.operationExpression)

Example 5 with WriteModification

use of software.amazon.awssdk.enhanced.dynamodb.extensions.WriteModification in project aws-sdk-java-v2 by aws.

the class PutItemOperation method addExpressionsIfExist.

private PutItemRequest.Builder addExpressionsIfExist(PutItemRequest.Builder requestBuilder, WriteModification transformation) {
    Expression originalConditionExpression = request.map(r -> Optional.ofNullable(r.conditionExpression()), r -> Optional.ofNullable(r.conditionExpression())).orElse(null);
    Expression mergedConditionExpression;
    if (transformation != null && transformation.additionalConditionalExpression() != null) {
        mergedConditionExpression = Expression.join(originalConditionExpression, transformation.additionalConditionalExpression(), " AND ");
    } else {
        mergedConditionExpression = originalConditionExpression;
    }
    if (mergedConditionExpression != null) {
        requestBuilder = requestBuilder.conditionExpression(mergedConditionExpression.expression());
        // Avoiding adding empty collections that the low level SDK will propagate to DynamoDb where it causes error.
        if (mergedConditionExpression.expressionValues() != null && !mergedConditionExpression.expressionValues().isEmpty()) {
            requestBuilder = requestBuilder.expressionAttributeValues(mergedConditionExpression.expressionValues());
        }
        if (mergedConditionExpression.expressionNames() != null && !mergedConditionExpression.expressionNames().isEmpty()) {
            requestBuilder = requestBuilder.expressionAttributeNames(mergedConditionExpression.expressionNames());
        }
    }
    return requestBuilder;
}
Also used : TransactWriteItem(software.amazon.awssdk.services.dynamodb.model.TransactWriteItem) DynamoDbAsyncClient(software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient) CompletableFuture(java.util.concurrent.CompletableFuture) Expression(software.amazon.awssdk.enhanced.dynamodb.Expression) Function(java.util.function.Function) PutItemEnhancedRequest(software.amazon.awssdk.enhanced.dynamodb.model.PutItemEnhancedRequest) Map(java.util.Map) WriteRequest(software.amazon.awssdk.services.dynamodb.model.WriteRequest) PutRequest(software.amazon.awssdk.services.dynamodb.model.PutRequest) EnhancedClientUtils(software.amazon.awssdk.enhanced.dynamodb.internal.EnhancedClientUtils) DynamoDbClient(software.amazon.awssdk.services.dynamodb.DynamoDbClient) PutItemEnhancedResponse(software.amazon.awssdk.enhanced.dynamodb.model.PutItemEnhancedResponse) TableSchema(software.amazon.awssdk.enhanced.dynamodb.TableSchema) WriteModification(software.amazon.awssdk.enhanced.dynamodb.extensions.WriteModification) TransactPutItemEnhancedRequest(software.amazon.awssdk.enhanced.dynamodb.model.TransactPutItemEnhancedRequest) Either(software.amazon.awssdk.utils.Either) Put(software.amazon.awssdk.services.dynamodb.model.Put) DefaultDynamoDbExtensionContext(software.amazon.awssdk.enhanced.dynamodb.internal.extensions.DefaultDynamoDbExtensionContext) DynamoDbEnhancedClientExtension(software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClientExtension) TableMetadata(software.amazon.awssdk.enhanced.dynamodb.TableMetadata) PutItemRequest(software.amazon.awssdk.services.dynamodb.model.PutItemRequest) PutItemResponse(software.amazon.awssdk.services.dynamodb.model.PutItemResponse) OperationContext(software.amazon.awssdk.enhanced.dynamodb.OperationContext) AttributeValue(software.amazon.awssdk.services.dynamodb.model.AttributeValue) Optional(java.util.Optional) SdkInternalApi(software.amazon.awssdk.annotations.SdkInternalApi) Expression(software.amazon.awssdk.enhanced.dynamodb.Expression)

Aggregations

WriteModification (software.amazon.awssdk.enhanced.dynamodb.extensions.WriteModification)6 AttributeValue (software.amazon.awssdk.services.dynamodb.model.AttributeValue)6 DynamoDbEnhancedClientExtension (software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClientExtension)5 Expression (software.amazon.awssdk.enhanced.dynamodb.Expression)5 TableMetadata (software.amazon.awssdk.enhanced.dynamodb.TableMetadata)5 Map (java.util.Map)4 Optional (java.util.Optional)4 CompletableFuture (java.util.concurrent.CompletableFuture)4 Function (java.util.function.Function)4 SdkInternalApi (software.amazon.awssdk.annotations.SdkInternalApi)4 OperationContext (software.amazon.awssdk.enhanced.dynamodb.OperationContext)4 TableSchema (software.amazon.awssdk.enhanced.dynamodb.TableSchema)4 DefaultDynamoDbExtensionContext (software.amazon.awssdk.enhanced.dynamodb.internal.extensions.DefaultDynamoDbExtensionContext)4 DynamoDbAsyncClient (software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient)4 DynamoDbClient (software.amazon.awssdk.services.dynamodb.DynamoDbClient)4 TransactWriteItem (software.amazon.awssdk.services.dynamodb.model.TransactWriteItem)4 Either (software.amazon.awssdk.utils.Either)4 Collection (java.util.Collection)3 List (java.util.List)3 EnhancedClientUtils.readAndTransformSingleItem (software.amazon.awssdk.enhanced.dynamodb.internal.EnhancedClientUtils.readAndTransformSingleItem)3