1

I am trying to do a conditional update on a field Score in my table based on the condition that marks to be updated are greater than the current score.

I have written following code ,

StudentDO temp = mapper.load(StudentDO.class, student.getId());
temp.setScore(marks);
ArrayList<AttributeValue> list = new ArrayList<AttributeValue>();
            list.add(new AttributeValue().withN(Oldmarks.toString()));

            Map<String,ExpectedAttributeValue> expectedAttributes = new 
                                                                                                                   HashMap<String,ExpectedAttributeValue>();

            ExpectedAttributeValue expectedAttributeValue = new 
                                                                                                     ExpectedAttributeValue().withAttributeValueList(list)
                                                                                                                                       .withComparisonOperator("GT");

            expectedAttributes.put("Score",expectedAttributeValue);
            mapper.save(temp, new DynamoDBSaveExpression().withExpected(expectedAttributes));

This is failing with this runtime exception

com.amazonaws.services.dynamodbv2.model.ConditionalCheckFailedException: The conditional request failed (Service: null; Status Code: 400; Error Code: ConditionalCheckFailedException; Request ID: null)

at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.amazonaws.services.dynamodbv2.local.embedded.DDBExceptionMappingInvocationHandler.handleDynamoDBLocalServiceException(DDBExceptionMappingInvocationHandler.java:87)
at com.amazonaws.services.dynamodbv2.local.embedded.DDBExceptionMappingInvocationHandler.invoke(DDBExceptionMappingInvocationHandler.java:66)
at com.sun.proxy.$Proxy19.updateItem(Unknown Source)
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper$SaveObjectHandler.doUpdateItem(DynamoDBMapper.java:854)
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper$2.executeLowLevelRequest(DynamoDBMapper.java:594)
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper$SaveObjectHandler.execute(DynamoDBMapper.java:733)
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.save(DynamoDBMapper.java:623)
at com.amazonaws.services.dynamodbv2.datamodeling.AbstractDynamoDBMapper.save(AbstractDynamoDBMapper.java:128)

I am not able to debug why is it throwing Conditional Check Failed Exception. I could make out the request is not properly formed , but not sure where is it malformed ?

I have tried to align it to these docs http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/datamodeling/DynamoDBSaveExpression.html

http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/model/ExpectedAttributeValue.html

http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/model/AttributeValue.html

My DB schema is this

@DynamoDBTable(tableName = "Student")

public class StudentDO {
    @DynamoDBHashKey(attributeName = "Id")
    private Integer id;

    @DynamoDBAttribute(attributeName = "Name")
    private String name;

    @DynamoDBAttribute(attributeName = "Score")
    private Integer score;

    @Override
    public String toString() {

        return "Student [Name=" + name + ", id=" + id + ", score=" + score + "]";
    }


}
2
  • Can you provide a little details about your Dynamo schema? Commented Apr 19, 2017 at 21:08
  • Updated the Schema in question Commented Apr 22, 2017 at 16:39

1 Answer 1

1

Each DynamoDB attribute must have a public getter and setter, since DynamoDBMapper works on JavaBeans (a class with a no argument constructor, and getters + setters for each private var). Modify your class to this:

@DynamoDBTable(tableName = "Student")
public class StudentDO {
    private Integer id;
    private String name;
    private Integer score;

    @DynamoDBAttribute(attributeName = "Id")
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @DynamoDBAttribute(attributeName = "Name")
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @DynamoDBAttribute(attributeName = "Score")
    public Integer getScore() {
        return score;
    }

    public void setScore(Integer score) {
        this.score = score;
    }

    @Override
    public String toString() {

        return "Student [Name=" + name + ", id=" + id + ", score=" + score + "]";

    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.