Spring Boot集成DynamoDB已声明@DynamoDBRangeKey仍报指定错误
解决DynamoDB Mapper报错:"SolarFarmData[created_millis]: no RANGE key value present"
我一眼就看出问题出在你同时使用了@Id注解和单独的@DynamoDBHashKey/@DynamoDBRangeKey注解上。在Spring Data DynamoDB体系里,@Id是用来标记复合主键的专属注解,当你给farmId加上@Id后,框架会默认它是唯一的单一主键,直接忽略你后续配置的@DynamoDBRangeKey。但你的数据表实际是分区键+排序键的复合结构,这就导致DynamoDB Mapper在加载数据时,找不到它预期中应该存在的范围键值,进而抛出报错。
快速修复方案
最直接的解决方式就是移除farmId上的@Id注解,让@DynamoDBHashKey和@DynamoDBRangeKey单独负责主键映射:
修改后的实体类代码:
@DynamoDBTable(tableName = "solar_farm_data") public class SolarFarmData { // 移除这里的@Id注解 private String farmId; private Double ambientTemperature; private Long createdMillis; @DynamoDBHashKey(attributeName = "farm_id") public String getFarmId() { return farmId; } public void setFarmId(String farmId) { this.farmId = farmId; } @DynamoDBRangeKey(attributeName = "created_millis") public Long getCreatedMillis() { return createdMillis; } public void setCreatedMillis(Long createdMillis) { this.createdMillis = createdMillis; } @DynamoDBAttribute(attributeName = "ambient_temperature") public Double getAmbientTemperature() { return ambientTemperature; } public void setAmbientTemperature(Double ambientTemperature) { this.ambientTemperature = ambientTemperature; } }
进阶方案:用复合主键类管理(可选)
如果你更习惯用@Id来统一管理复合主键,可以创建一个专门的主键类:
// 注意要实现Serializable接口 public class SolarFarmDataKey implements Serializable { private String farmId; private Long createdMillis; @DynamoDBHashKey(attributeName = "farm_id") public String getFarmId() { return farmId; } public void setFarmId(String farmId) { this.farmId = farmId; } @DynamoDBRangeKey(attributeName = "created_millis") public Long getCreatedMillis() { return createdMillis; } public void setCreatedMillis(Long createdMillis) { this.createdMillis = createdMillis; } }
然后在实体类中引用这个主键类:
@DynamoDBTable(tableName = "solar_farm_data") public class SolarFarmData { @Id private SolarFarmDataKey id; private Double ambientTemperature; // getter和setter方法 public SolarFarmDataKey getId() { return id; } public void setId(SolarFarmDataKey id) { this.id = id; } @DynamoDBAttribute(attributeName = "ambient_temperature") public Double getAmbientTemperature() { return ambientTemperature; } public void setAmbientTemperature(Double ambientTemperature) { this.ambientTemperature = ambientTemperature; } }
不过针对你的场景,第一种直接移除@Id的方案更简单高效,能快速解决当前的报错问题。
内容的提问来源于stack exchange,提问作者samir kanta lenka
相关产品推荐
相关产品推荐

