Chen Harel
Chen Harel

Reputation: 10062

Building a general DynamoDBMarshalling for enums

I'm using Amazon Web Services SDK for Java for DynamoDB; trying to suffice the interface for @DynamoDBMarshalling:

Class<? extends DynamoDBMarshaller<? extends Object>> marshallerClass();

I build a marshaller that receives any Enum:

public class EnumMarshaller<T extends Enum<T>> implements DynamoDBMarshaller<T>
{
    @Override
    public String marshall(T getterReturnResult)
    {
        return getterReturnResult.toString();
    }

    @Override
    public T unmarshall(Class<T> clazz, String obj)
    {
        return Enum.valueOf(clazz, obj);
    }
}

The problem is that when I'm trying to use the annotation on my field I can't figure it out:

public static enum MyEnum {BLA, BLA2}

@DynamoDBMarshalling(marshallerClass=EnumMarshaller<MyEnum>.class)
    public MyEnum getStatus()
    {
        return status;
    }

I can't call .class on a generic type and some other tries came up different errors. I'm starting to think it's impossible with Amazon's contract...

Upvotes: 12

Views: 5254

Answers (2)

Tiago Peres Fran&#231;a
Tiago Peres Fran&#231;a

Reputation: 3215

The following worked fine to me:

The Marshaller:

public class EnumMarshaller implements DynamoDBMarshaller<Enum> {
    @Override
    public String marshall(Enum getterReturnResult) {
        return getterReturnResult.name();
    }

    @Override
    public Enum unmarshall(Class<Enum> clazz, String obj) {
        return Enum.valueOf(clazz, obj);
    }
}

In my table class with an enum:

@DynamoDBMarshalling(marshallerClass=EnumMarshaller.class)
@DynamoDBAttribute(attributeName = "MyEnum")
public MyEnum getMyEnum() {
   return myEnum;
}

Upvotes: 17

Joe
Joe

Reputation: 41

I worked around this problem by sub-classing the JsonMarshaller with a specific class type:

public class FooMarshaller extends JsonMarshaller<Foo>
{
    // No impl required
}

Then the marshalling annotation is added to the data property like:

@DynamoDBMarshalling(marshallerClass = FooMarshaller.class)
public Set<Foo> getFoos()
{
    return foos;
}

A pain if you have to add many class types, but it works.

Upvotes: 4

Related Questions