Joy
Joy

Reputation: 4473

Unique constraint on combination of multiple columns within a partition key in DynamoDB

I am new to DynamoDB. As part of a requirement in my current project I would like to have a unique constraint on combination of two columns (col1, col2) within a given partition key.

I could have achieved that by making combination col1+col2 a range key. But the problem is, either or both of these two columns might get updated. So if I try to update range key, DynamoDB will throw a exception.

I cannot achieve that in application level also as it is not single threaded. Also I cannot make a separate table with the given columns on which I want to impose unique constraint, as this will not solve the problem as application is distributed.

I have no other idea how to achieve that.

EDIT:

I am trying to solve with following approach:

DynamoDBSaveExpression saveExpression = new DynamoDBSaveExpression();
    Map expected = new HashMap();
    expected.put("ID",      <----- this is partition key
            new ExpectedAttributeValue(new AttributeValue(student.getID())).withExists(false));
    expected.put("rollNum",    
        new ExpectedAttributeValue(new AttributeValue(student.getRollNum())).withExists(false));
    expected.put("name", 
            new ExpectedAttributeValue(new AttributeValue(student.getName())).withExists(false));

    saveExpression.setExpected(expected);
    saveExpression.setConditionalOperator(ConditionalOperator.AND);
    rbsDynamoDBClient.getDynamoDBMapper().save(student, saveExpression);

But I am getting following exception:

 Caused by: 
 com.amazonaws.services.dynamodbv2.model.AmazonDynamoDBException: One 
 or more parameter values were invalid: Value cannot be used when 
 Exists is false for Attribute: ID (Service: AmazonDynamoDBv2; Status 
 Code: 400; Error Code: ValidationException;

Same error is coming for other fields i.e. rollNum and name too.

Upvotes: 2

Views: 902

Answers (1)

S&#233;bastien Coste
S&#233;bastien Coste

Reputation: 309

Replace

expected.put("ID", new ExpectedAttributeValue(new AttributeValue(student.getID())).withExists(false));

with

 expected.put("ID", new ExpectedAttributeValue(false));

In ExpectedAttributeValue you say what you expect as it's not what is in your object. When you expect it not to exists, the value checked is the one in your object, so you don't need to provide it

Upvotes: 4

Related Questions