AWS SDK Java版DynamoDB查询报错:表达式中使用的属性值未定义(涉及保留关键字处理)
Fixing DynamoDB Query Error: "Invalid KeyConditionExpression: An expression attribute value used in expression is not defined"
Let's break down what's going wrong here and fix your code step by step:
Key Issues in Your Current Code
- Missing Expression Attribute Values: Your error specifically calls out
:typeValuenot being defined — that's because you're using placeholders like:typeValueand:partialIdValuein yourkeyConditionExpression, but never mapping those placeholders to actual values via theexpressionAttributeValuesparameter. - Incorrect Expression Syntax: You're directly inserting Java variable names (like
idKey,idValue) into the expression string, which creates invalid, unrecognized placeholders for DynamoDB. - Wrong Order in Key Condition: DynamoDB requires that the partition key condition comes first in the
keyConditionExpression, followed by the sort key condition (you had them reversed).
Corrected Code
DynamoDBClient dynamoDbClient = DynamoDbClient.builder() .region(Region.EU_WEST_1) .credentialsProvider(StaticCredentialsProvider.create(awsCredentials)) .build(); String typeValue = "typeValue"; String partialIdValue = "partialIdValue"; // Renamed for clarity String tableName = "your-table-name"; // Handle reserved keyword "Type" with Expression Attribute Names Map<String, String> expressionNames = new HashMap<>(); expressionNames.put("#t", "Type"); // Map placeholders to actual values with Expression Attribute Values Map<String, AttributeValue> expressionValues = new HashMap<>(); expressionValues.put(":typeVal", AttributeValue.builder().s(typeValue).build()); expressionValues.put(":idPartial", AttributeValue.builder().s(partialIdValue).build()); QueryRequest request = QueryRequest.builder() .tableName(tableName) // Partition key condition first, then sort key begins_with condition .keyConditionExpression("#t = :typeVal AND begins_with(Id, :idPartial)") .expressionAttributeNames(expressionNames) .expressionAttributeValues(expressionValues) // Don't forget this critical parameter! .build(); QueryResponse response = dynamoDbClient.query(request);
What Changed & Why
- Added
expressionAttributeValues: This maps the intentional placeholders (:typeVal,:idPartial) to real values that DynamoDB can interpret. Each value is wrapped in anAttributeValuematching the data type of your DynamoDB attributes (string type with.s()here). - Fixed
keyConditionExpression:- Put the partition key condition (
#t = :typeVal) first — this is a non-negotiable requirement for DynamoDB Query operations. - Used clear, explicit placeholders instead of inserting Java variables directly. The sort key
Idisn't a reserved keyword, so we can reference it directly in the expression.
- Put the partition key condition (
- Renamed variables for clarity:
partialIdValuemakes it obvious this is the partial string we're matching against the sort key.
Additional Notes
- Always separate expression placeholders from actual values: this avoids syntax errors, protects against injection risks, and keeps your code maintainable.
- For Query operations, the
keyConditionExpressionmust include an equality match on the partition key. You can only add sort key conditions using supported operators likebegins_with,between,=,<,>, etc. - Double-check that your attribute names (like
Id) match exactly with the case used in your DynamoDB table — DynamoDB is case-sensitive for attribute names.
内容的提问来源于stack exchange,提问作者Raisus
相关产品推荐
相关产品推荐

