2016-07-15 51 views
0

我想在DynamoDB中为我的对象实现更改历史记录。简单的做法是将“对象ID”指定为散列值,将“更新时间”指定为范围键。但是,java sdk不允许注释键始终自动生成(如果没有注释便利性,更改值似乎工作正常)。为什么?为什么DynamoDB java sdk不允许始终自动生成密钥?

示例代码:

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

例外:

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) 

回答

0

你的用例是典型的。通常你不希望对象的散列和范围键发生改变。事实上,我会尽可能说它不鼓励。

事实上,使用DynamoDB时,项目的唯一特征是它的关键(无论是分区键还是分区+范围键),所以更改范围键本质上会创建一个新的项目,这在技术上不是更新。

我不知道这是否准确代表之所以混合@DynamoDBAutoGeneratedTimestamp@DynamoDBRangeKey没有在SDK的支持,但它肯定是有原因的。