2016-03-29 2 views
0

У меня есть таблица DynamoDB, называемая «inbox». В нем будут храниться сообщения, которые отправляются пользователям и от них. Будут более одного типа сообщений, и в зависимости от типа данные могут появляться вместе с сообщением. У меня есть объект UserMessage, который сопоставляется с таблицей входящих сообщений. Хотя для всех сообщений будут общие поля (например, sendTo, sentFrom), данные будут отличаться по своей структуре.DynamoDBMappingException при использовании Java Generics

Вместо того, чтобы использовать карту для этих данных, возникает мысль, что использование Java Generics может быть лучшим подходом. У меня есть объект, аннотированный с помощью @DynamoDBDocument, и DynamoDBMapper будет сериализовать это для JSON. Когда переменная-член объявляется как:

private ContactData data; 

Действительно, результат ожидается. данные сериализуются в JSON и сохраняются в атрибуте данных во входящих почтовых ящиках в формате аннотаций ContactData. Однако, чтобы получить желаемую гибкость при использовании общих типов, вызов DynamoDBMapper.save() вызывает DynamoDBMappingException: невозможно преобразовать T в класс.

Вот класс UserMessage:

@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; 
    } 
} 

И код КонтактныеДанные:

@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; 
} 
} 

Код контроллера задать этот вопрос является:

UserMessage<ContactData> message = new UserMessage<ContactData>(); 
ContactData cd = new ContactData(); 
cd.setEmail("[email protected]"); 
cd.setFirstname("Jane"); 
cd.setLastname("Smith"); 

message.setToId("[email protected]"); 
message.setData(cd) 
DynamoDB.getMapper().save(message); 

Я довольно неопытные и общие типы для меня совершенно новые, поэтому я надеюсь, что правильно их использую. Я думаю, что я. Я просто думаю, что в этом случае DynamoDBMapper не может отобразиться в нужный класс. Thanks Jeff

ответ

0

Каждый раз, когда вы используете нестандартный класс атрибутов, вам необходимо предоставить маршаллеру. Здесь я использовал глобальный маршаллер объектов, который вы, вероятно, можете использовать только 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; 
     } 
    } 
} 
Смежные вопросы