DynamoDB Mapper annotation for Object which has list of another object

constantLeaner picture constantLeaner · Mar 4, 2019 · Viewed 8.3k times · Source

I am trying to create a dynamoDBMapper annotation for the below case.

I have EmployeeLevelTrail which is a class of a Employee level record

@DynamoDBTable(tableName = TABLE_NAME)
public class EmployeeData {
    public final static String TABLE_NAME = “EmployeeDataRecord”;

    @DynamoDBAttribute(attributeName = “employeeID”)
    public String EmployeeID;

    @DynamoDBAttribute(attributeName = “EmployeeLevelDataRecords”)
    @DynamoDBTyped(DynamoDBMapperFieldModel.DynamoDBAttributeType.M)
    public EmployeeLevelTrail employeeLevelTrail

}


public class EmployeeLevelTrail {

    public final static String DDB_ATTR_EMPLOYEE_LEVEL_TRAIL = “employeeLevelTrail”;

    @DynamoDBAttribute(attributeName = DDB_ATTR_EMPLOYEE_LEVEL_TRAIL)
    private List<EmployeeLevelRecord> thisEmployeeLevelRecords;

    public void appendEmployeeLevelRecord(@NonNull EmployeeLevelRecord employeeLevelRecord) {

        thisEmployeeLevelRecords.add(employeeLevelRecord);

    }
}


public class EmployeeLevelRecord {

    private String Level;

    private String Manager;

    private Instant timeOfEvent;

}

This is my annotation but it is not correct as I am not able to save my DynamoDB data

Answer

Matthew Pope picture Matthew Pope · Mar 4, 2019

To mark another class as part of the data model for DynamoDBMapper, you can annotate it with @DynamoDBDocument, which tells DynamoDBMapper that a class can be serialized as a DynamoDB document.

For classes that you aren't writing (ie. from the Java library or an external library) or if you need more control over how to serialize one of your own classes, you can use @DynamoDBTypeConverted, which allows you to map arbitrary data by providing your own DynamoDBTypeConverter implementation to convert from any Java object to any supported DynamoDB type.

Using your sample code, I've added in the appropriate @DynamoDBDocument and @DynamoDBTypeConverted annotations, as well as a sample implementation of a DynamoDBTypeConverter that converts an Instant to a ISO-8601 String. If employeeId is the hash key of your table, make sure you also add the @DynamoDBHashKey annotation to employeeId.

@DynamoDBTable(tableName = TABLE_NAME)
public class EmployeeData {
    public final static String TABLE_NAME = “EmployeeDataRecord”;

    @DynamoDBAttribute(attributeName = “employeeID”)
    public String EmployeeID;

    @DynamoDBAttribute(attributeName = “EmployeeLevelDataRecords”)
    public EmployeeLevelTrail employeeLevelTrail

}

@DynamoDBDocument
public class EmployeeLevelTrail {

    public final static String DDB_ATTR_EMPLOYEE_LEVEL_TRAIL = “employeeLevelTrail”;

    @DynamoDBAttribute(attributeName = DDB_ATTR_EMPLOYEE_LEVEL_TRAIL)
    private List<EmployeeLevelRecord> thisEmployeeLevelRecords;

    public void appendEmployeeLevelRecord(@NonNull EmployeeLevelRecord employeeLevelRecord) {

        thisEmployeeLevelRecords.add(employeeLevelRecord);

    }
}

@DynamoDBDocument
public class EmployeeLevelRecord {

    private String Level;

    private String Manager;

    @DynamoDBTypeConverted(converter = InstantToStringTypeConverter.class)
    private Instant timeOfEvent;

}

public class InstantToStringTypeConverter implements DynamoDBTypeConverter<String, Instant> {

    @Override
    public String convert(final Instant instant) {
        return instant.toString();
    }

    @Override
    public Instant unconvert(final String string) {
        return Instant.parse(string);
    }
}