我正在尝试为AWS实现一个简单的java事件处理器lambda。它接收sqs事件,并对dynamoDB表进行适当的更新。
此表中的属性之一是具有4个已定义状态的状态字段;因此,我想在java中使用一个枚举类,并将其Map到这个属性。
在AWS SDK v1中,我可以使用@DynamoDBTypeConvertedEnum注解。但在v2中它不再存在。取而代之的是@DynamoDbConvertedBy(),它接收转换器类引用。还有一个EnumAttributeConverter类,它应该可以很好地与它一起工作。
但由于某种原因,它不起作用。下面是我当前代码的一个片段:
@Data
@DynamoDbBean
@NoArgsConstructor
public class Task{
@Getter(onMethod_ = {@DynamoDbPartitionKey})
String id;
...
@Getter(onMethod_ = {@DynamoDbConvertedBy(EnumAttributeConverter.class)})
ExportTaskStatus status;
}
枚举如下所示:
@RequiredArgsConstructor
public enum TaskStatus {
@JsonProperty("running") PROCESSING(1),
@JsonProperty("succeeded") COMPLETED(2),
@JsonProperty("cancelled") CANCELED(3),
@JsonProperty("failed") FAILED(4);
private final int order;
}
有了这个,我在启动应用程序时得到以下异常:
Class 'class software.amazon.awssdk.enhanced.dynamodb.internal.converter.attribute.EnumAttributeConverter' appears to have no default constructor thus cannot be used with the BeanTableSchema
5条答案
按热度按时间2mbi3lxu1#
对于其他来到这里的人来说,在我看来,从enum中删除annotation完全可以正常工作,即SDK隐式应用提供的属性转换器。这在Github问题中也提到了。我自己的类看起来像这样(Brand在这里是一个enum),并且在获取项目时转换enum没有任何问题。
h43kikqp2#
如何将Java Enums与Amazon DynamoDB和AWS SDK v2配合使用?
尽管documentation没有说明,但
DynamoDbConvertedBy
注解要求您提供的任何AttriuteConverter
包含parameterles默认构造函数不幸的是编写许多内置
AttributeConverter
类的人决定使用静态create()
方法而不是构造函数来示例化它们(也许它们是隐藏的单例?我不知道)。这意味着任何想要使用这些有用的构造函数的人-较少的类,如InstantAsStringAttributeConverter
和EnumAttributeConverter
需要将它们 Package 在自定义 Package 器类中,这些 Package 器类简单地模仿我们使用create
示例化的转换器。对于非泛型类型类,如InstantAsStringAttributeConverter
,这很简单。只需创建一个 Package 器类,它会模仿你用create()
新建的示例,并引用它:然后更新注解以指向该类,而不是实际的底层库类。
但是等等,
EnumAttributeConverter
是一个泛型类型类,这意味着你需要更进一步。首先,你需要创建一个转换器的版本,它 Package 了官方版本,但依赖于一个接受类型的构造函数,而不是静态示例化:但这只完成了一半--现在我们需要为每个想要转换的枚举类型生成一个版本,该类型子类化我们的自定义类:
一个二个一个一个
或者Lombok岛的方式:
这是一个痛苦。这是一个痛苦,可以通过一点调整和AWS SDK中的一点反射来解决,但这就是我们现在所处的位置。
xurqigkl3#
我认为你的注解可能是这里的问题。我会删除所有提到构造函数的注解,而是写出你自己的构造函数。对于
Task
和TaskStatus
。qnyhuwrf4#
dynamodb增强的SDK开箱即用。
当你声明一个
@DynamoDbBean
时,DefaultAttributeConverterProvider
提供了一长串在java类型之间转换属性的可能方法,包括一个EnumAttributeConverter
,如果type.rawClass().isEnum()
为true,则使用它。如果您想要扩展转换器的数量,您需要添加
converterProviders
注解参数,并声明默认值(或省略它),以及您想要的任何其他提供程序。示例:
@DynamoDbBean(converterProviders = { DefaultAttributeConverterProvider.class, MyCustomAttributeConverterProvider.class });
iyr7buue5#
基于watkinsmatthewp的解决方案答案:
任务状态属性如下所示: