DynamoDB含两个自动生成属性时scan获取全部条目报错
问题解决:DynamoDBMapper scan() 类型映射错误(expected N in value {S: ...})
错误原因
你的Employee模型中timestamp字段定义为Long类型,DynamoDBMapper读取数据时期望该字段是数字类型(N),但数据库中实际存储的是**字符串类型(S)**的时间值(比如2022-12-09T09:23:52.737Z),类型不匹配导致映射失败。
解决方案
方案1:修正数据库数据类型(推荐)
如果是开发环境,直接清空employee表后重新插入数据即可——@DynamoDBAutoGeneratedTimestamp注解会自动生成毫秒级的Long类型时间戳,确保数据库中该字段类型为数字。
如果是生产环境,需要批量更新现有数据:
- 遍历所有Employee条目,将字符串格式的时间转换为对应的毫秒级时间戳(例如
2022-12-09T09:23:52.737Z转换为1670580232737) - 用DynamoDB的批量更新API将转换后的数值写入对应字段
方案2:添加自定义类型转换器(兼容旧数据)
如果不想修改现有数据库数据,可以自定义类型转换器,让DynamoDBMapper自动完成字符串时间到Long时间戳的转换:
- 创建转换器类:
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTypeConverter; import java.time.Instant; import java.time.format.DateTimeParseException; public class StringToLongTimestampConverter implements DynamoDBTypeConverter<Long, String> { @Override public Long convert(String s) { try { Instant instant = Instant.parse(s); return instant.toEpochMilli(); } catch (DateTimeParseException e) { throw new IllegalArgumentException("无效的时间戳格式", e); } } @Override public String unconvert(Long aLong) { return Instant.ofEpochMilli(aLong).toString(); } }
- 在
Employee类的timestamp字段上添加转换器注解:
@DynamoDBTypeConverted(converter = StringToLongTimestampConverter.class) @DynamoDBAutoGeneratedTimestamp(strategy = DynamoDBAutoGenerateStrategy.ALWAYS) private Long timestamp;
额外说明
移除timestamp字段后方法正常,是因为此时DynamoDBMapper不需要处理该字段的类型映射,自然不会触发类型不匹配的错误。
内容的提问来源于stack exchange,提问作者Gourav Kumar
相关产品推荐
相关产品推荐

