DynamoDBMapper provides an easy way to map POJOs to data in DynamoDB.
Most of the code POJOs are verbose and it makes a perfect sense to use Immutables to reduce boilerplate.
NOTE: provided snippets show the idea that could be improved and / or modified to address specific needs.
In the project with more than one entity it makes sense to create custom Style that would allow
to enable Immutables for POJO.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.CLASS)
@Value.Style(
create = "new",
isInitialized = "wasInitialized",
allParameters = true,
beanFriendlyModifiables = true,
passAnnotations = {
DynamoDBTable.class,
DynamoDBHashKey.class,
DynamoDBRangeKey.class,
DynamoDBAttribute.class,
DynamoDBTyped.class,
DynamoDBTypeConvertedEnum.class
// more DynamoDB annotations to be added
}
)
public @interface DynamoDBStyle {}
Application of the newly created style could look like:
@DynamoDBStyle
@Value.Immutable
@Value.Modifiable
@DynamoDBTable(tableName = "people")
public interface Person {
@DynamoDBHashKey(attributeName = "name")
String getName();
@DynamoDBAttribute(attributeName = "age")
int getAge();
}
We apply both @Value.Immutable and @Value.Modifiable. The former is bread and butter
of Immutables as it provides all nice features while the latter enables usage
of generated classes with DynamoDBMapper. DynamoDBMapper
expects the POJO to have no-arg ctor with setters and newly created DynamoDBStyle
annotation configures Immutables to generated the required structure.
The usage is pretty straightforward with only one caveat: Modifiable... implementation
should be used any time data is loaded from the DynamoDB.
// assuming mapper is an instance of `DynamoDBMapper`
Person john = ImmutablePerson.of("John", 42);
mapper.save(john);
john = mapper.load(ModifiablePerson.class, "John");
System.out.println(john); // prints ModifiablePerson{name=John, age=42}