Search code examples
javaamazon-web-servicesamazon-dynamodbaws-java-sdk

AWS DynamoDB Java SDK alternative to annotations


I want to avoid using DynamoDB Annotations on a class but still be able to use a mapper to write and read from DynamoDB. I am using the Java SDK to read and write from DynamoDB (using the provided DynamoDBMapper.

Say I have this Model.java

@DynamoDBTable(tableName="Model")
public class Model {

    private Integer id;
    private String title;

    @DynamoDBHashKey(attributeName="ModelId")  
    public Integer getId() { return id;}
    public void setId(Integer id) {this.id = id;}

    @DynamoDBAttribute(attributeName="Title")  
    public String getTitle() {return title; }
    public void setTitle(String title) { this.title = title; }
}

I would write to it as usual

Model model = new Model();
//... random information

DynamoDBMapper mapper = new DynamoDBMapper(client);
mapper.save(model);

This is fine but my domain object is littered with DynamoDB specific annotations. Is there a way to instead have a class that wrapped the domain object (without any annotations). In the case below I would be looking for an effective implementation of DynamoDBModelWrapper

public class Model {
    private Integer id;
    private String title;

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

    public String getTitle() {return title; }
    public void setTitle(String title) { this.title = title; }
}

public class DynamoDBModelWrapper extends Model { ... }

Model model = new Model();
//... random information

DynamoDBMapper mapper = new DynamoDBMapper(client);
mapper.save(DyanamoDBModelWrapper(model));

Cheers and thank you


Solution

  • This seems like a really bad idea. You would effectively have to force all of your table keys and indexes to have the same name. The model-wrapper can't just apply the same annotation to each model attribute, it has to know which annotation to apply to which attribute, which would mean still applying annotations to the model class, or since this is not allowed, forcing the model class to name attributes in a particular way. For example your primary hash key attribute might have to be called primaryhashkey.

    Also you would not be able to use some of the really powerful parts of DyanmoDBMapper like complex and arbitrary data mapping.

    One thing to mention is that you could tidy things up at least. You have some superfluous text in your model class. You only need to specify attributeName if the name of your model attribute is different to the table attribute. If they match you can simply omit it. The same is true for the model class name and the tableName. So you can do:

    Table schema:
    TableName: Model
    Partition Key Attribute: id
    Attribute: title
    

    And then your model class would look like this

    @DynamoDBTable
    public class Model {
    
        private Integer id;
        private String title;
    
        @DynamoDBHashKey  
        public Integer getId() { return id;}
        public void setId(Integer id) {this.id = id;}
    
        @DynamoDBAttribute 
        public String getTitle() {return title; }
        public void setTitle(String title) { this.title = title; }
    }
    

    The annotations are still there but it looks a lot neater.