DynamoDB DeleteItem in Java (AWS SDK v2)

A delete in AWS SDK for Java 2.x is a DeleteItemRequest carrying the full primary key, and ReturnValue.ALL_OLD tells you whether anything was actually there.

Add a conditionExpression to the code below and it develops a bug that still compiles. The first bullet under the snippet is that bug.

Code

import java.util.HashMap;
import java.util.Map;

import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.DeleteItemRequest;
import software.amazon.awssdk.services.dynamodb.model.DeleteItemResponse;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.model.ReturnValue;

public class DeleteItemExample {
    public static void main(String[] args) {
        try (DynamoDbClient ddb = DynamoDbClient.builder()
                .region(Region.US_EAST_1)
                .build()) {

            Map<String, AttributeValue> key = new HashMap<>();
            key.put("Artist", AttributeValue.builder().s("Arturo Sandoval").build());
            key.put("SongTitle", AttributeValue.builder().s("Cubano Chant").build());

            DeleteItemRequest request = DeleteItemRequest.builder()
                    .tableName("Music")
                    .key(key)
                    .returnValues(ReturnValue.ALL_OLD)
                    .build();

            DeleteItemResponse response = ddb.deleteItem(request);
            if (response.attributes().isEmpty()) {
                System.out.println("No item with that key existed");
            } else {
                System.out.println("Deleted: " + response.attributes());
            }
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
        }
    }
}

Explanation

  • ConditionalCheckFailedException extends DynamoDbException — so the catch block above swallows a failed guard and prints it as though the service had broken. Once the request carries a conditionExpression, catch the narrower type first. A condition that did its job is an outcome, not an error.
  • The exception carries the losing item — put returnValuesOnConditionCheckFailure(ReturnValuesOnConditionCheckFailure.ALL_OLD) on the request and e.item() hands back the row as DynamoDB saw it. AWS states the price: "No read capacity units are consumed."
  • attributes() never returns null — a delete that matched nothing yields an empty map, so isEmpty() is the test. hasAttributes() is what separates "the service returned nothing" from "the service returned an empty map".
  • The ReturnValue enum is shared with UpdateItemreturnValues(ReturnValue.ALL_NEW) compiles here and comes back as a ValidationException, because "DeleteItem does not recognize any values other than NONE or ALL_OLD". The builder's String overload hides the same mistake (the full set).
  • Emptying a table is not an API callDeleteItem deletes exactly one key, and nothing in the SDK deletes many. Truncating a table is a Scan for keys followed by batched writes, and usually loses to DeleteTable plus CreateTable.

Do it visually

If the attribute you guard on is a reserved word, the condition needs a # alias. The reserved-word checker tells you which of your attribute names sit on AWS's 573-word list and generates the expressionAttributeNames map for the ones that do.

DynoTable stages a delete into a Pending changes panel before it reaches the table. Cmd+Backspace stages the selected rows, Cmd+Shift+Backspace deletes and commits in one move, and anything staged can be discarded. Download DynoTable.

References

Last verified 2026-07-28 against the official AWS documentation linked above.

Work with DynamoDB without the Console

A fast DynamoDB desktop client that runs the real SQL DynamoDB can’t — JOINs, GROUP BY, aggregates — with visual editing and an AI agent on your own Bedrock keys.

Free 30-day trial, no credit card — then the Free plan with no time limit.