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.