0

timestamp ("creationDate")를 범위로 사용하여 dynamodb 테이블을 얻었습니다. 모델은 사용하기 쉽도록 joda DateTime을 사용합니다 (나머지 코드와의 호환성). 이 범위에서 쿼리를 수행 할 수 있도록 테이블의 특성에 대해 숫자 형식을 사용하고이를 Java 타임 스탬프 (시간별 밀리 초)로 저장하려고했습니다. 그런 다음 moda를 추가하여 joda DateTime을 long을 나타내는 String으로 변환하고 그 반대의 경우도 마찬가지입니다.AWS DynamoDB 개체 지속성 모델에서 joda DateTime 범위 키 사용

테이블 구조 (생성) :

void CreateTable() 
{ 
    CreateTableRequest createTableRequest = new CreateTableRequest().withTableName(LinkManager.TABLE_NAME); 

    ProvisionedThroughput pt = new ProvisionedThroughput() 
     .withReadCapacityUnits(LinkManager.READ_CAPACITY_UNITS) 
     .withWriteCapacityUnits(LinkManager.WRITE_CAPACITY_UNITS); 

    createTableRequest.setProvisionedThroughput(pt); 

    ArrayList<AttributeDefinition> ad = new ArrayList<AttributeDefinition>(); 

    ad.add(new AttributeDefinition().withAttributeName("creationDate").withAttributeType(ScalarAttributeType.N)); 
    ad.add(new AttributeDefinition().withAttributeName("contentHash").withAttributeType(ScalarAttributeType.S)); 

    createTableRequest.setAttributeDefinitions(ad); 

    ArrayList<KeySchemaElement> ks = new ArrayList<KeySchemaElement>(); 
    ks.add(new KeySchemaElement().withAttributeName("contentHash").withKeyType(KeyType.HASH)); 
    ks.add(new KeySchemaElement().withAttributeName("creationDate").withKeyType(KeyType.RANGE)); 

    createTableRequest.setKeySchema(ks); 

    this.kernel.DDB.createTable(createTableRequest); 
} 

모델 :

@DynamoDBTable(tableName="Link") 
public class Link { 
    private String ContentHash; 
    private DateTime CreationDate; 

    @DynamoDBHashKey(attributeName = "contentHash") 
    public String getContentHash() { 
     return ContentHash; 
    } 
    public void setContentHash(String contentHash) { 
     ContentHash = contentHash; 
    } 

    @DynamoDBRangeKey(attributeName = "creationDate") 
    @DynamoDBMarshalling(marshallerClass = DateTimeMarshaller.class) 
    public DateTime getCreationDate() { 
     return CreationDate; 
    } 
    public void setCreationDate(DateTime creationDate) { 
     CreationDate = creationDate; 
    } 
} 

마샬 :

Exception in thread "main" com.amazonaws.AmazonServiceException: Type of specified attribute inconsistent with type in table (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException; Request ID: 8aabb703-cb44-4e93-ab47-c527a5aa7d52) 
: 나는 다음과 같은 오류가

public class DateTimeMarshaller extends JsonMarshaller<DateTime> 
{ 
    public String marshall(DateTime dt) 
    { 
     return String.valueOf(dt.getMillis()); 
    } 

    public DateTime unmarshall(String dt) 
    { 
     long ldt = Long.parseLong(dt); 
     return new DateTime(ldt); 
    } 
} 

marshaller가 String을 반환하고 dynamoDB가 숫자 유형을 원하기 때문에 속성 유형이 N 인 것 같아요.이 경우 사람들이 무엇을하는지 모르겠지만 솔루션을 검색했지만 찾지 못했습니다. 그것. 지역 Dynamob 인스턴스에서만 테스트했는데 차이점이 없다고 생각합니다 (유효성 검사가 실패 했으므로 요청이 없습니다).

확실한 해결 방법은 모델의 날짜에 긴 형식을 사용하고 특수한 getter 및 setter를 추가하여 DateTime에서 작업하는 것입니다. 아직도, 더 깨끗한 방법이 있습니까? 나는 모델에서 DatTime 범위를 사용하는 유일한 사람이 아니라고 확신합니다.

답변

0

Range 키를 사용하여 String 자체로 테이블을 다시 만듭니다. 긴 숫자로 채워질 경우에도 S는 Marshaller와의 호환성을 보장합니다

+0

예, 범위 키의 "between"쿼리를 수행 할 수 없으므로 처음에는 N이에요. @DynamoDBIgnore를 사용하여 DateTime을 사용하기 위해 모델에 특정 접근자를 추가하고 날짜를 오래 선언했습니다. – cplc

+0

멋진 솔루션 :) –