如何在AWS SDK v2的Amazon DynamoDB中使用Java Enum并解决转换异常
AWS SDK v2 DynamoDB 枚举类型映射异常解决方案
错误原因
AWS SDK v2 内置的EnumAttributeConverter没有提供无参构造函数,它需要在实例化时传入目标枚举类作为参数,因此直接在@DynamoDbConvertedBy注解中传入EnumAttributeConverter.class会因为框架无法完成实例化抛出异常。
解决方案
方案一:继承内置转换器实现(适配默认枚举名存储)
如果你的DynamoDB表中status字段存储的是枚举实例名(如PROCESSING、COMPLETED),只需要继承EnumAttributeConverter实现自定义转换器类,提供无参构造传入枚举类型即可:
import software.amazon.awssdk.enhanced.dynamodb.internal.converter.attribute.EnumAttributeConverter; public class TaskStatusConverter extends EnumAttributeConverter<TaskStatus> { public TaskStatusConverter() { super(TaskStatus.class); } }
修改Task类中status字段的注解配置:
@Getter(onMethod_ = {@DynamoDbConvertedBy(TaskStatusConverter.class)}) TaskStatus status;
方案二:自定义转换器实现(适配自定义值存储)
如果你需要将@JsonProperty中定义的字符串(如running、succeeded)存储到DynamoDB,需要自行实现AttributeConverter接口完成转换逻辑:
import com.fasterxml.jackson.annotation.JsonProperty; import software.amazon.awssdk.enhanced.dynamodb.AttributeConverter; import software.amazon.awssdk.enhanced.dynamodb.AttributeValueType; import software.amazon.awssdk.enhanced.dynamodb.EnhancedType; import software.amazon.awssdk.services.dynamodb.model.AttributeValue; public class TaskStatusConverter implements AttributeConverter<TaskStatus> { @Override public AttributeValue transformFrom(TaskStatus status) { if (status == null) { return null; } try { JsonProperty jsonProperty = status.getClass().getField(status.name()).getAnnotation(JsonProperty.class); return AttributeValue.builder().s(jsonProperty.value()).build(); } catch (NoSuchFieldException e) { throw new RuntimeException("枚举状态解析失败", e); } } @Override public TaskStatus transformTo(AttributeValue attributeValue) { if (attributeValue == null || attributeValue.s() == null) { return null; } String dbValue = attributeValue.s(); for (TaskStatus status : TaskStatus.values()) { try { JsonProperty jsonProperty = status.getClass().getField(status.name()).getAnnotation(JsonProperty.class); if (jsonProperty.value().equals(dbValue)) { return status; } } catch (NoSuchFieldException e) { throw new RuntimeException("枚举状态解析失败", e); } } throw new IllegalArgumentException("未知的状态值: " + dbValue); } @Override public EnhancedType<TaskStatus> type() { return EnhancedType.of(TaskStatus.class); } @Override public AttributeValueType attributeValueType() { return AttributeValueType.S; } }
同样将status字段的@DynamoDbConvertedBy注解指定为上述自定义转换器类即可。
内容的提问来源于stack exchange,提问作者3Fish
相关产品推荐
相关产品推荐

