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

DynamoDB查询时DynamoDBMappingException异常求助

DynamoDB查询映射异常排查与解决

问题现象

查询DynamoDB数据时触发以下映射异常,实体类已配置注解、Getter/Setter及转换器逻辑,问题持续未解决:

com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMappingException: POSTable[ProductIdentificationDetails]; could not unconvert attribute
Caused by: com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMappingException: could not invoke null on class with value Optional[ProductIdentificationDetails(identificationNumbers=[serialNumber2, serialNumber1, serialNumber3], capturedTime=Fri Apr 12 10:23:38 UTC 2024, userId=32886492417)] of type class java.util.Optional at com.amazonaws.services.dynamodbv2.datamodeling.StandardBeanProperties$MethodReflect.set(StandardBeanProperties.java:136) ~[AWSPersistenceJavaClient-1.12.x.jar:?]
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperFieldModel.set(DynamoDBMapperFieldModel.java:111) ~[AWSPersistenceJavaClient-1.12.x.jar:?]
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperFieldModel.unconvertAndSet(DynamoDBMapperFieldModel.java:164) ~[AWSPersistenceJavaClient-1.12.x.jar:?]
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperTableModel.unconvert(DynamoDBMapperTableModel.java:267) ~[AWSPersistenceJavaClient-1.12.x.jar:?]
... 97 more
Caused by: java.lang.NullPointerException at com.amazonaws.services.dynamodbv2.datamodeling.StandardBeanProperties$MethodReflect.set(StandardBeanProperties.java:133) ~[AWSPersistenceJavaClient-1.12.x.jar:?]
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperFieldModel.set(DynamoDBMapperFieldModel.java:111) ~[AWSPersistenceJavaClient-1.12.x.jar:?]
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperFieldModel.unconvertAndSet(DynamoDBMapperFieldModel.java:164) ~[AWSPersistenceJavaClient-1.12.x.jar:?]
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperTableModel.unconvert(DynamoDBMapperTableModel.java:267) ~[AWSPersistenceJavaClient-1.12.x.jar:?]
... 97 more

相关代码

实体类Getter/Setter

public void setProductIdentificationDetails(final ProductIdentificationDetails productIdentificationDetails) {
    this.productIdentificationDetails = Optional.ofNullable(productIdentificationDetails);
}

@DynamoDBMarshalling(marshallerClass = ProductIdentificationDetailsConverter.class)
@DynamoDBAttribute(attributeName = "ProductIdentificationDetails")
public Optional<ProductIdentificationDetails> getProductIdentificationDetails() {
    log.info("debug : " + this.productIdentificationDetails);
    return this.productIdentificationDetails;
}

表类注解

@Builder
@NoArgsConstructor
@AllArgsConstructor (access = AccessLevel.PRIVATE)
@Log4j
@DynamoDBTable

转换器逻辑

@Log4j
public class ProductIdentificationDetailsConverter implements DynamoDBMarshaller<Optional<ProductIdentificationDetails>>
{
    @Override
    public String marshall(final Optional<ProductIdentificationDetails> object) {
        return object.isPresent() ? IonUtility.toString(object.get()) : null;
    }

    @Override
    public Optional<ProductIdentificationDetails> unmarshall(final Class<Optional<ProductIdentificationDetails>> clazz,
            final String serializedObject) {
        try {
            return (StringUtils.isNotEmpty(serializedObject)
                    ? Optional.of(IonUtility.toObject(serializedObject, ProductIdentificationDetails.class))
                    : Optional.empty());
        } catch (final IllegalArgumentException e) {
            throw new IllegalArgumentException("ProductIdentificationDetails De-serialization Failed", e);
        }
    }
}

问题根源

DynamoDBMapper反序列化时,会根据Getter方法的返回类型(Optional<ProductIdentificationDetails>)寻找对应Setter方法,期望Setter参数类型与Getter返回类型一致。但当前Setter参数是ProductIdentificationDetails而非Optional<ProductIdentificationDetails>,导致Mapper无法找到匹配的Setter方法,反射调用时抛出空指针异常。

解决方案

修改Setter方法的参数类型为Optional<ProductIdentificationDetails>,确保与Getter返回类型一致:

public void setProductIdentificationDetails(final Optional<ProductIdentificationDetails> productIdentificationDetails) {
    this.productIdentificationDetails = productIdentificationDetails;
}

如果需要保留原有业务逻辑(处理非Optional参数),可以重载Setter方法,同时保留符合Mapper要求的版本:

// 供DynamoDBMapper调用的Setter
public void setProductIdentificationDetails(final Optional<ProductIdentificationDetails> productIdentificationDetails) {
    this.productIdentificationDetails = productIdentificationDetails;
}

// 业务代码使用的Setter
public void setProductIdentificationDetails(final ProductIdentificationDetails productIdentificationDetails) {
    this.productIdentificationDetails = Optional.ofNullable(productIdentificationDetails);
}

另外,检查Lombok的@Builder或@AllArgsConstructor配置,确保构造方法参数类型与实体类字段类型一致,避免Mapper实例化对象时出现类型不匹配问题。

内容的提问来源于stack exchange,提问作者Kancharla Aishwarya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 16:03:14