Nicholas Muir
Nicholas Muir

Reputation: 3104

DynamoDB and Android: The provided key element does not match the schema

I am a little confused with the hash keys and authorization for aws dynamodb. I checked the other answer and they all refer to hash keys index keys or index range keys. I am not sure which one is which and what relates to the partition and sort key (are they the same)? If they are not is there a way of changing your hash/index keys after the table is created?

My overview of my table name sets my partition key and primary sort key as follows:

Table name Music Primary partition key Artist (String) Primary sort key SongTitle (String)

This is my model code (Ignore the name of the class):

@DynamoDBTable(tableName = "Music")
public class SongDatabaseMappingAdapter {

    private String artist;
    private String songtitle;
    private String albumtitle;
    private String category;
    private int musicianrating;
    private int userrating;
    private String pictureurl;
    private String songurl;

    @DynamoDBHashKey(attributeName = "Artist")
    public String getArtist() {
        return artist;
    }

    public void setArtist(String artist) {
        this.artist = artist;
    }

    @DynamoDBIndexRangeKey(attributeName = "SongTitle")
    public String getSongTitle() {
        return songtitle;
    }

    public void setSongTitle(String songtitle) {
        this.songtitle = songtitle;
    }


    @DynamoDBAttribute(attributeName = "AlbumTitle")
    public String getAlbumTitle() {
        return albumtitle;
    }

    public void setAlbumTitle(String albumtitle) {
        this.albumtitle = albumtitle;
    }


    @DynamoDBAttribute(attributeName = "Category")
    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }


    @DynamoDBAttribute(attributeName = "MusicianRating")
    public int getMusicianRating() {
        return musicianrating;
    }

    public void setMusicianRating(int musicianrating) {
        this.musicianrating = musicianrating;
    }


    @DynamoDBAttribute(attributeName = "UserRating")
    public int getUserRating() {
        return userrating;
    }

    public void setUserRating(int userrating) {
        this.userrating = userrating;
    }


    @DynamoDBAttribute(attributeName = "PictureURL")
    public String getPictureURL() {
        return pictureurl;
    }

    public void setPictureURL(String pictureurl) {
        this.pictureurl = pictureurl;
    }


    @DynamoDBAttribute(attributeName = "SongURL")
    public String getSongURL() {
        return songurl;
    }

    public void setSongURL(String songurl) {
        this.songurl = songurl;
    }


}

And then I am testing a database write with this basic code:

public class addArtist extends AsyncTask  {

    @Override
    protected Object doInBackground(Object[] params) {

        SongDatabaseMappingAdapter song = new SongDatabaseMappingAdapter();
        song.setSongTitle("Great Expectations");
        song.setArtist("Charles Dickens");
        song.setUserRating(1299);
        song.setAlbumTitle("1234567890");
        mapper.save(song);
        return null;
    }
}

And this is the error I get:

com.amazon.mysampleapp E/AndroidRuntime:  Caused by: com.amazonaws.AmazonServiceException: The provided key element does not match the schema (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException; Request ID: 7441R7SOQVDBT2BJL6IN58QCTVVV4KQNSO5AEMVJF66Q9ASUAAJG)

Thanks for your help

Upvotes: 0

Views: 1636

Answers (1)

Bhavdip Sagar
Bhavdip Sagar

Reputation: 1971

You define the annotation @DynamoDBIndexRangeKey which is wrong that's why it throw the exception: "The provided key element does not match the schema".

I see that in your table "SongTitle" is sort key (Also call Range key) but in your class you taken as the Index Range Key that is actually not Index Range key it is simple sort key (Range key).So the solution is to replace the annotation @DynamoDBIndexRangeKey with @DynamoDBRangeKey over the getSongTitle().

I hope this can help you.

Thank you

Upvotes: 1

Related Questions