Store Java enum's String value instead of enum value itself in DynamoDB

I'm using DynamoDB and I would like to store the enum's String values instead of the enum itself.

For instance, I have this enum:

public enum Source { BREACH("breach"), LEAKAGE("leakage"); private final String desc; Source(String desc) { this.desc = desc; } public String desc() { return desc; } } 

...and this "entity":

@DynamoDBTable(tableName = "Alerts") public final class Alert implements Serializable { private static final long serialVersionUID = 4012517315640518044L; @DynamoDBHashKey(attributeName = "AlertId") // Partition Key or Hash Attribute private String alertId; @DynamoDBTypeConvertedEnum @DynamoDBAttribute(attributeName = "Source") private Source type; // Constructor(s), Getter(s), Setter(s), ToString, etc... } 

With the @DynamoDBTypeConvertedEnum annotation, the value that gets saved is BREACH, but I want breach.

{ "AlertId": { "S": "a083168d-cb23-4ec8-ab80-a1c16955c4b8" }, "Source": { "S": "BREACH" }, ... "CreatedAt": { "S": "2017-05-03T14:07:36.395Z" } } 

Any clues? I did try "converters" (not fully, I couldn't make it work though) but I think I have to end up doing one for each enum type since they are all different.

3 Answers

You can code the Alert class like this i.e. define the attribute as String and design the getter and setter to send/receive enum object (i.e. Source).

Alert class:-

 @DynamoDBTable(tableName = "Alerts") public final class Alert implements Serializable { private static final long serialVersionUID = 4012517315640518044L; private String alertId; private String type; @DynamoDBHashKey(attributeName = "AlertId") public String getAlertId() { return alertId; } @DynamoDBAttribute(attributeName = "Source") public Source getType() { if (type != null) return Source.valueOf(type); else return null; } public void setAlertId(String alertId) { this.alertId = alertId; } public void setType(Source type) { this.type = type.desc(); } } 

Create Alert:-

Stores the value as expected on database table. The get item from DynamoDB table also works fine.

public Boolean createAlert(String alertId, Source source) { DynamoDBMapper dynamoDBMapper = new DynamoDBMapper(dynamoDBClient); Alert alert = new Alert(); alert.setAlertId(alertId); alert.setType(source); dynamoDBMapper.save(alert); return true; } 
4

Override toString() this should work.

public enum Source { BREACH("breach"), LEAKAGE("leakage"); private final String desc; Source(String desc) { this.desc = desc; } public String desc() { return desc; } @Override public String toString() { return desc; } } 

I solved it by defining a custom attribute converter. It works but I'm afraid you'd have to write converters for each enum.

There is already method for serializing desc().We can define a static method for deserializing toSource() Source.java

public enum Source { BREACH("breach"), LEAKAGE("leakage"); private final String desc; Source(String desc) { this.desc = desc; } public String desc() { return desc; } public static Source toSource(String value) { return Arrays.stream(Source.values()).filter(et -> et.desc().equals(value)).findFirst().orElse(null); } } 

We can then define a custom DynamoDBType converter:

SourceEnumDynamoDbConverter.java

public class SourceEnumDynamoDbConverter implements DynamoDBTypeConverter<String, Source> { @Override public String convert(Source source) { return source.desc(); } @Override public Source unconvert(String sourceStr) { return Source.toSource(sourceStr); } } 

And finally annotate our Entity's Source property with this custom converter Alert.java

@DynamoDBTable(tableName = "Alerts") public final class Alert implements Serializable { private static final long serialVersionUID = 4012517315640518044L; @DynamoDBHashKey(attributeName = "AlertId") // Partition Key or Hash Attribute private String alertId; private Source type; @DynamoDBTypeConverted(converter = TrialEnumDynamoDbConverter.class) @DynamoDBAttribute(attributeName = "Source") public Source getSource() { return type; } public void setSource(Source type) { this.type = type; } // Constructor(s), Getter(s), Setter(s), ToString, etc... } 

This way desc is stored and read from dynamodb resulting in

{ "AlertId": { "S": "a083168d-cb23-4ec8-ab80-a1c16955c4b8" }, "Source": { "S": "breach" }, ... "CreatedAt": { "S": "2017-05-03T14:07:36.395Z" } } 

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like