2016-07-15 8 views
0

Ich möchte Änderungsverlauf für meine Objekte in DynamoDB implementieren. Eine einfache Möglichkeit wäre, "Objekt-ID" als Hash und "aktualisierte Zeit" als Bereichsschlüssel anzugeben. Java sdk lässt jedoch nicht zu, dass Beschriftungsschlüssel immer automatisch generiert werden (das Ändern des Werts ohne Annotation scheint zu funktionieren). Warum?Warum DynamoDB Java SDK nicht immer automatisch generierte Schlüssel erlaubt?

Beispielcode:

@DynamoDBTable(tableName = "data") 
public class Person { 

    public static void main(String[] args) { 
     AmazonDynamoDBClient client = new AmazonDynamoDBClient() 
       .withEndpoint("http://localhost:8000"); 
     DynamoDBMapper mapper = new DynamoDBMapper(client); 

     TableUtils.deleteTableIfExists(client, mapper.generateDeleteTableRequest(Person.class)); 
     TableUtils.createTableIfNotExists(client, mapper.generateCreateTableRequest(Person.class) 
       .withProvisionedThroughput(new ProvisionedThroughput(1L, 1L)) 
     ); 

     Person person = new Person(); 
     person.setPersonId("abc"); 

     mapper.save(person); 
     mapper.save(person); 

     TableUtils.deleteTableIfExists(client, mapper.generateDeleteTableRequest(Person.class)); 
    } 

    @DynamoDBHashKey 
    private String personId; 

    @DynamoDBRangeKey 
    @DynamoDBAutoGeneratedTimestamp 
    private Long updated; 

    public String getPersonId() { 
     return personId; 
    } 

    public void setPersonId(String personId) { 
     this.personId = personId; 
    } 

    public Long getUpdated() { 
     return updated; 
    } 

    public void setUpdated(Long updated) { 
     this.updated = updated; 
    } 
} 

Ausnahme:

Exception in thread "main" com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMappingException: Field com.dynamodb.testpackage.Person[updated] must not have auto-generated key with ALWAYS strategy 
    at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperFieldModel$Builder.build(DynamoDBMapperFieldModel.java:797) 
    at com.amazonaws.services.dynamodbv2.datamodeling.StandardModelFactories$SchemaFactory.newTableModel(StandardModelFactories.java:118) 
    at com.amazonaws.services.dynamodbv2.datamodeling.StandardModelFactories$SchemaFactory.getTableModel(StandardModelFactories.java:86) 
    at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.getTableModel(DynamoDBMapper.java:401) 
    at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.generateCreateTableRequest(DynamoDBMapper.java:2432) 
    at com.dynamodb.testpackage.Person.main(Person.java:21) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:497) 
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147) 

Antwort

0

Ihr Anwendungsfall ist atypisch. Normalerweise möchten Sie nicht, dass sich der Hash- und Bereichsschlüssel eines Objekts ändert. In der Tat würde ich so weit gehen zu sagen, dass es entmutigt ist.

Mit DynamoDB wird ein Element eindeutig durch seinen Schlüssel charakterisiert (ob nur Partitionsschlüssel oder Partition + Bereichsschlüssel), so dass das Ändern des Bereichsschlüssels im Wesentlichen ein neues Element erstellt, das technisch kein Update ist.

Ich bin mir nicht sicher, ob dies genau stellt den Grund, warum @DynamoDBAutoGeneratedTimestamp Mischen und @DynamoDBRangeKey nicht im SDK unterstützt, aber es ist sicherlich ein Grund.