我有一个名为' inbox'的DynamoDB表。在其中将存储发送给用户和从用户发送的消息。将有多种类型的消息,并且基于类型,数据可能随消息一起出现。我有一个映射到收件箱表的对象UserMessage。虽然所有消息都有公共字段(例如sendTo,sentFrom),但数据结构会有所不同。
使用Java Generics可能是一种更好的方法,而不是使用Map来表示这些数据。我有一个使用@DynamoDBDocument注释的对象,DynamoDBMapper会将其序列化为JSON。当成员变量声明为:
时@DynamoDBTable(tableName="inbox")
public class UserMessage<T> {
private String toId;
private T data;
@DynamoDBAttribute(attributeName="data")
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
@DynamoDBHashKey(attributeName="toId")
public String getToId() {
return toId;
}
public void setToId(String to) {
this.toId = to;
}
}
确实,结果是预料之中的。数据被序列化为JSON并以ContactData的注释格式存储在收件箱的data属性中。但是,为了通过使用泛型类型获得所需的灵活性,对DynamoDBMapper.save()的调用会抛出DynamoDBMappingException:无法将T转换为类。
这是UserMessage类:
@DynamoDBDocument
public class ContactData {
private String firstname;
private String lastname;
private String email;
@DynamoDBAttribute(attributeName = "firstname")
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
@DynamoDBAttribute(attributeName = "lastname")
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
@DynamoDBAttribute(attributeName = "email")
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
ContactData的代码:
UserMessage<ContactData> message = new UserMessage<ContactData>();
ContactData cd = new ContactData();
cd.setEmail("jane@test.com");
cd.setFirstname("Jane");
cd.setLastname("Smith");
message.setToId("test@email.com");
message.setData(cd)
DynamoDB.getMapper().save(message);
设置它的控制器代码是:
{{1}}
我相当缺乏经验,而且通用类型对我来说是全新的,所以我希望我正确使用它们。我觉得我是。我只是认为DynamoDBMapper在这种情况下无法映射到正确的类。 谢谢 杰夫
答案 0 :(得分:0)
每次使用非标准属性类时,都需要提供编组器。在这里,我使用了一个全局的Object marshaller,您可以使用 JSON-ify 任何您想要的东西。
我个人更喜欢使用静态类型,每个类型都有一个我可以推理的定义的编组器,但是ymmv。
public class GenericDBEntity<T>
{
..
private T extra;
@DynamoDBAttribute
@DynamoDBMarshalling(marshallerClass=ObjectMarshaller.class)
public T getExtra()
{
return extra;
}
public void setExtra(T extra)
{
this.extra = extra;
}
public static class ObjectMarshaller implements DynamoDBMarshaller<Object>
{
@Override
public String marshall(Object getterReturnResult)
{
return getterReturnResult.toString();
}
@Override
public Object unmarshall(Class<Object> clazz, String obj)
{
return obj;
}
}
}