为何删除DynamoDB不存在项无报错?如何实现不存在则抛异常?
Great question! I’ve hit this exact quirk with DynamoDBMapper before—by default, the delete() method operates on a "best-effort" basis. Even if the item you’re trying to delete doesn’t exist, it won’t throw an error or return any indication that nothing happened. That’s because it’s wrapping DynamoDB’s underlying DeleteItem API, which behaves the same way by design.
But luckily, you can fix this with a conditional delete expression to enforce that the item must exist before deletion. Here’s how to do it step by step:
Step 1: Understand the Condition Expression Trick
DynamoDB lets you add a ConditionExpression to delete operations. We’ll use the attribute_exists() function to check if the item’s primary key attribute exists. If the item doesn’t exist, this condition fails, and DynamoDB will throw a ConditionalCheckFailedException—exactly what you want.
Step 2: Code Example
Let’s assume you have a simple entity class mapped to your DynamoDB table (e.g., a User table with a userId hash key):
@DynamoDBTable(tableName = "Users") public class User { private String userId; private String fullName; @DynamoDBHashKey(attributeName = "userId") public String getUserId() { return userId; } public void setUserId(String userId) { this.userId = userId; } @DynamoDBAttribute(attributeName = "fullName") public String getFullName() { return fullName; } public void setFullName(String fullName) { this.fullName = fullName; } }
Now, modify your delete logic to include the conditional expression:
// Create a dummy user object with the ID you want to delete User userToDelete = new User(); userToDelete.setUserId("non-existent-user-id"); // Build the delete expression with a condition DynamoDBDeleteExpression deleteExpression = new DynamoDBDeleteExpression() .withConditionExpression("attribute_exists(userId)"); // Check if the primary key exists try { dynamoDbMapper.delete(userToDelete, deleteExpression); System.out.println("Success: Item existed and was deleted."); } catch (ConditionalCheckFailedException e) { System.err.println("Error: Item does not exist—delete aborted."); // Here you can throw a custom exception, log details, or handle the failure as needed }
Alternative: Explicit Primary Key Match
If you prefer, you can also check that the primary key value matches exactly (though this is redundant if you’ve already set the key on your object, but it works too):
DynamoDBDeleteExpression deleteExpression = new DynamoDBDeleteExpression() .withConditionExpression("userId = :userId") .withExpressionAttributeValues( Map.of(":userId", new AttributeValue().withS(userToDelete.getUserId())) );
Key Notes
- Exception Type: Make sure you’re catching
com.amazonaws.services.dynamodbv2.model.ConditionalCheckFailedException—this is the specific exception thrown when the condition isn’t met. - Composite Primary Keys: If your table uses a hash + sort key, just add a check for the sort key attribute too (e.g.,
attribute_exists(userId) AND attribute_exists(sortKey)). - Performance: The conditional check adds negligible overhead—DynamoDB already has to locate the item to delete, so this is just an extra quick validation step.
This approach ensures you get explicit feedback when trying to delete an item that doesn’t exist, instead of silent failures.
内容的提问来源于stack exchange,提问作者Manthan Jamdagni

