You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot从DynamoDB读取Double触发NumberFormatException问题求助

问题:DynamoDB SDK将Double解析为Integer触发NumberFormatException

问题场景

开发Spring Boot应用时,使用AWS SDK从DynamoDB读取数据,遇到SDK错误地将Double类型字段按Integer解析,抛出NumberFormatException的问题。使用的AWS SDK版本为1.12.454,代码库中所有overallEnergy的引用均为Double类型。

实体类代码

import com.amazonaws.services.dynamodbv2.datamodeling.*;
import lombok.*;
import org.springframework.data.annotation.Id;

import java.time.LocalDate;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@DynamoDBTable(tableName = "my_table")
public class MyEntity {

    @Id
    @Getter(value = AccessLevel.NONE)
    private MyKey myKey;
    
    // Other attributes...
    
    @DynamoDBAttribute(attributeName = "overall_energy")
    @DynamoDBTyped(DynamoDBMapperFieldModel.DynamoDBAttributeType.N)
    private Double overallEnergy;
    
    // Other attributes...

}

DynamoDB中的目标数据

{
  "overall_energy": {
    "N":  "29985.689834184945"
  }
}

错误日志

Jun  9 22:20:39 ip-10-55-167-190 web: at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
Jun  9 22:20:39 ip-10-55-167-190 web: Caused by: java.lang.NumberFormatException: For input string: "29985.689834184945"
Jun  9 22:20:39 ip-10-55-167-190 web: at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67) ~[na:na]
Jun  9 22:20:39 ip-10-55-167-190 web: at java.base/java.lang.Integer.parseInt(Integer.java:668) ~[na:na]
Jun  9 22:20:39 ip-10-55-167-190 web: at java.base/java.lang.Integer.valueOf(Integer.java:999) ~[na:na]
Jun  9 22:20:39 ip-10-55-167-190 web: at com.amazonaws.services.dynamodbv2.datamodeling.StandardTypeConverters$ToInteger$2.convert(StandardTypeConverters.java:773) ~[aws-java-sdk-dynamodb-1.12.454.jar!/:na]
Jun  9 22:20:39 ip-10-55-167-190 web: at com.amazonaws.services.dynamodbv2.datamodeling.StandardTypeConverters$ToInteger$2.convert(StandardTypeConverters.java:770) ~[aws-java-sdk-dynamodb-1.12.454.jar!/:na]
Jun  9 22:20:39 ip-10-55-167-190 web: at com.amazonaws.services.dynamodbv2.datamodeling.StandardTypeConverters$1.unconvert(StandardTypeConverters.java:75) ~[aws-java-sdk-dynamodb-1.12.454.jar!/:na]
Jun  9 22:20:39 ip-10-55-167-190 web: at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTypeConverter$DelegateConverter.unconvert(DynamoDBTypeConverter.java:109) ~[aws-java-sdk-dynamodb-1.12.454.jar!/:na]
Jun  9 22:20:39 ip-10-55-167-190 web: at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTypeConverter$NullSafeConverter.unconvert(DynamoDBTypeConverter.java:128) ~[aws-java-sdk-dynamodb-1.12.454.jar!/:na]
Jun  9 22:20:39 ip-10-55-167-190 web: at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTypeConverter$ExtendedConverter.unconvert(DynamoDBTypeConverter.java:88) ~[aws-java-sdk-dynamodb-1.12.454.jar!/:na]
Jun  9 22:20:39 ip-10-55-167-190 web: at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperFieldModel.unconvert(DynamoDBMapperFieldModel.java:146) ~[aws-java-sdk-dynamodb-1.12.454.jar!/:na]
Jun  9 22:20:39 ip-10-55-167-190 web: at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperFieldModel.unconvertAndSet(DynamoDBMapperFieldModel.java:164) ~[aws-java-sdk-dynamodb-1.12.454.jar!/:na]
Jun  9 22:20:39 ip-10-55-167-190 web: at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperTableModel.unconvert(DynamoDBMapperTableModel.java:267) ~[aws-java-sdk-dynamodb-1.12.454.jar!/:na]

已尝试的解决步骤

  • 创建自定义转换器StringToDoubleTypeConverter,期望显式转换解决问题,仍抛出NumberFormatException
  • 移除@DynamoDBTyped注解,让DynamoDBMapper隐式处理转换,问题未解决
  • 修改DynamoDB中overall_energy的值为两位小数,仍触发异常
  • 将overall_energy改为整数值,异常消失,但不符合应用需求

原因分析

问题根源在于AWS SDK的类型转换器匹配逻辑:当使用@DynamoDBTyped(DynamoDBAttributeType.N)时,SDK会优先尝试匹配范围更窄的严格数字类型,Integer的范围比Double更窄,导致SDK错误选择Integer转换器处理带小数的数字字符串。此外,实体类中其他字段(如MyKey)的注解配置可能干扰了转换器选择的上下文逻辑。

解决方案

方案1:显式绑定自定义类型转换器

创建自定义转换器,并通过@DynamoDBTypeConverted注解强制SDK使用该转换器处理字段,同时移除原有的@DynamoDBTyped注解避免冲突:

import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTypeConverter;

public class StringToDoubleConverter implements DynamoDBTypeConverter<String, Double> {
    @Override
    public String convert(Double object) {
        return object != null ? object.toString() : null;
    }

    @Override
    public Double unconvert(String object) {
        return object != null ? Double.valueOf(object) : null;
    }
}

修改实体类字段:

@DynamoDBAttribute(attributeName = "overall_energy")
@DynamoDBTypeConverted(converter = StringToDoubleConverter.class)
private Double overallEnergy;

方案2:升级AWS SDK版本

旧版本SDK的类型匹配逻辑存在bug,升级到1.12.500及以上的1.12.x版本,新版本优化了数字类型转换器的选择逻辑,会优先根据实体类字段类型匹配对应转换器。

方案3:清理字段映射冲突

检查实体类中其他属性的注解配置,比如MyKey类中的字段是否存在不当的@DynamoDBTyped配置,避免干扰overallEnergy字段的转换器选择上下文。


内容的提问来源于stack exchange,提问作者Carlo Ligthart

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 08:40:05