3

Is there a clean way to map Optional fields with DynamoDBMapper, for both basic types and arbitrary/custom objects?

I believe one option would be to implement DynamoDBTypeConverter for optionals of basic types (Optional<String>, Optional<Integer>, etc). But, in addition to being a bit dirty, this would not work for custom objects.

I am looking for some sort of "chaining" behaviour of converters, where the default converter is applied first and the result wrapped in case of optional fields.

Is there a way to specify this behaviour?

@DynamoDBTable
public class MyModel {
   @DynamoDBAttribute
   private Optional<String> someStringField;

   @DynamoDBAttribute
   private Optional<AnotherModel> someAnotherModelField;

   ...
}

@DynamoDBDocument
public class AnotherModel {
}
madhead
  • 31,729
  • 16
  • 153
  • 201
ergomes
  • 121
  • 1
  • 4
  • Can you put a '@DynamoDBDocument' annotation on the 'AnotherModel' class? That will eliminate the need for chained converters. – Matthew Pope Jul 24 '19 at 16:24
  • Hi @MatthewPope, thanks for your reply. I am doing that already. The question is about being able to map Optional fields, though. – ergomes Jul 24 '19 at 23:14

1 Answers1

0

For what you want to do, I believe the custom converters is the proper way.

Create a class for example:

class SomeAnotherModelOptionalConverter implements DynamoDBTypeConverter<String, Optional<AnotherModel>> {

    @Override
    public String convert(Optional<AnotherModel> optional) {
        // your conversion from Optional attribute to String DynamoDB attribute

    }

    @Override
    public Optional<AnotherModel> unconvert(String s) {
        // your conversion from String DynamoDB attribute to Optional

    }
}

Then on your attribute, you add the following tag:


@DynamoDBAttribute
@DynamoDBTypeConverted(converter = SomeAnotherModelOptionalConverter.class)
private Optional<AnotherModel> someAnotherModelField;

Anyways, I would not use an Optional as a field in a class. Instead I would create a getter that has and Optional as a return.

private AnotherModel someAnotherModelField

...
Optional<AnotherModel> getSomeAnotherModelField(){
   return Optional.ofNullable(someAnotherModelField);
}

Let me know if that works for you!

Gonzalo Saad
  • 66
  • 1
  • 4