Java,DynamoDB:可以定制一套marsall吗?

Java,DynamoDB:可以定制一套marsall吗?,java,spring,amazon-web-services,amazon-dynamodb,Java,Spring,Amazon Web Services,Amazon Dynamodb,我需要注释一个具有Set属性的类。编组标量UUID很好,我可以使用@DynamoDBMarshalling注释指定我的转换器,一切正常 当尝试在集合上使用相同的转换器时,我得到“DynamoDBMappingException:Expected SS in value”。我尝试创建一个自定义转换器,该转换器需要设置,但同样的问题仍然存在 可以定制马歇尔集吗 @DynamoDBTable(tableName="djones-test") public class UUIDRecommendatio

我需要注释一个具有
Set
属性的类。编组标量
UUID
很好,我可以使用
@DynamoDBMarshalling
注释指定我的转换器,一切正常

当尝试在
集合
上使用相同的转换器时,我得到“DynamoDBMappingException:Expected SS in value”。我尝试创建一个自定义转换器,该转换器需要
设置
,但同样的问题仍然存在

可以定制马歇尔集吗

@DynamoDBTable(tableName="djones-test")
public class UUIDRecommendation {
    private UUID id;
    private Set<UUID> recommendations;

    @DynamoDBHashKey
    @DynamoDBMarshalling(marshallerClass=UuidConverter.class)
    public UUID getId() {
        return id;
    }

    public void setId(UUID id) {
        this.id = id;
    }

    //Neither this nor UuidConverter.class work here    
    @DynamoDBMarshalling(marshallerClass=SetUuidConverter.class)
    public Set<UUID> getRecommendations() {
        return recommendations;
    }

    public void setRecommendations(Set<UUID> recommendations) {
        this.recommendations = recommendations;
    }
}

哦,天哪-看起来不可能有客户的集合管理员。AWS SDK硬编码为仅处理单个字符串值(SUnmarshaller())

AWS SDK 1.3.13第185行中的发电机反射镜:

if ( isCustomMarshaller(getter) ) {
    unmarshaller = new SUnmarshaller() {

        @Override
        public Object unmarshall(AttributeValue value) {
            return getCustomMarshalledValue(toReturn, getter, value);
        }
    };
}
更新

作为一个完全肮脏的黑客,我通过复制/粘贴整个类拼凑了一些东西:(这就是为什么私有静态最终实用程序服务不好,依赖注入好的原因

这将起作用,因此您可以使用一个客户转换器(
UuidConverter
,在我的例子中)作为返回
UUID
实例或
Set
实例的getter

我添加了一个名为getCustomMarshalledValueSet的方法,该方法迭代value.getSS()返回的列表,为每个值调用自定义封送拆收器,并将结果添加到它返回的集合中

    @SuppressWarnings({ "rawtypes", "unchecked" })
    private <T> T getCustomMarshalledValueSet(T toReturn, Method getter, AttributeValue value) {
    DynamoDBMarshalling annotation = getter.getAnnotation(DynamoDBMarshalling.class);
    Class<? extends DynamoDBMarshaller<? extends Object>> marshallerClass = annotation.marshallerClass();

    DynamoDBMarshaller marshaller;
    try {
        marshaller = marshallerClass.newInstance();
    } catch (InstantiationException e) {
        throw new DynamoDBMappingException("Couldn't instantiate marshaller of class " + marshallerClass, e);
    } catch (IllegalAccessException e) {
        throw new DynamoDBMappingException("Couldn't instantiate marshaller of class " + marshallerClass, e);
    }

    Set<T> set = new HashSet<T>();

    for (String part : value.getSS()) {
        set.add((T) marshaller.unmarshall(getter.getReturnType(), part));
    }

    return (T) set;
}

试试这个。它在getter/setter中处理marshall/unmarshall。我使用类似的技术存储包含JSON的
Set
,但在我的代码中作为
Set
访问它。我不使用getter/setter,而是使用方便的方法

以下是修改后的版本:

@DynamoDBTable(tableName="djones-test")
public class UUIDRecommendation {
    private String id;
    // custom object representation in JVM
    private Set<UUID> recommendations;

    private static final JsonMarshaller<UUID> UUID_MARSHALLER = new JsonMarshaller<UUID>();

    @DynamoDBHashKey(attributeName="id")
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }

    // Set<String> holding JSON in DynamoDB
    @DynamoDBAttribute(attributeName="recommendations")
    public Set<String> getRecommendations() {
        if (recommendations != null) {
            Set<String> jsonSet = new HashSet<String>(recommendations.size());
            for (UUID recommendation : recommendations) {
                String json = UUID_MARSHALLER.marshall(recommendation);
                jsonSet.add(json);
            }
            return jsonSet;
        } else {
            return null;
        }
    }
    public void setRecommendations(Set<String> jsonSet) {
        if (jsonSet != null) {
            recommendations = new HashSet<UUID>(jsonSet.size());
            for (String json : jsonSet) {
                UUID recommendation = UUID_MARSHALLER.unmarshall(UUID.class, json);
                recommendations.add(recommendation);
            }
        }
    }

    // convenience methods
    @DynamoDBIgnore
    public UUID convenienceMethod(UUID recommendation) {
        return null;
    }

    // custom object
    public class UUID {

    }
}
@DynamoDBTable(tableName=“djones测试”)
公共类UUIDRecommendation{
私有字符串id;
//JVM中的自定义对象表示
私人建议;
私有静态final JsonMarshaller UUID_MARSHALLER=new JsonMarshaller();
@DynamoDBHashKey(attributeName=“id”)
公共字符串getId(){
返回id;
}
公共无效集合id(字符串id){
this.id=id;
}
//在DynamoDB中设置JSON
@DynamoDBAttribute(attributeName=“建议”)
公共集合getRecommensions(){
如果(建议!=null){
Set jsstart=newhashset(recommendations.size());
对于(UUID建议:建议){
字符串json=UUID_MARSHALLER.marshall(推荐);
添加(json);
}
返回初始值;
}否则{
返回null;
}
}
公共无效集合建议(集合JSISTANCE){
if(jsstart!=null){
建议=新的HashSet(jsostate.size());
for(字符串json:JSONET){
UUID建议=UUID_MARSHALLER.unmarshall(UUID.class,json);
建议.增加(建议);
}
}
}
//便利方法
@发电机
公共UUID便利性方法(UUID建议){
返回null;
}
//自定义对象
公共类UUID{
}
}

我附加了一个修改版的DynamoDBReflector,用于处理aribtrary对象集的序列化/反序列化。我已经使用了一段时间,效果很好。

这很好!有点奇怪,他们没有包含一个特定的函数来完成此操作,但这是一个很好的解决方法,谢谢!
            if (isCustomMarshaller(getter)) {
                if (isCollection) {
                    unmarshaller = new SSUnmarshaller() {

                        @Override
                        public Object unmarshall(AttributeValue value) {
                            return getCustomMarshalledValueSet(toReturn, getter, value);
                        }
                    };
                } else {
                    unmarshaller = new SUnmarshaller() {

                        @Override
                        public Object unmarshall(AttributeValue value) {
                            return getCustomMarshalledValue(toReturn, getter, value);
                        }
                    };
                }

            }
@DynamoDBTable(tableName="djones-test")
public class UUIDRecommendation {
    private String id;
    // custom object representation in JVM
    private Set<UUID> recommendations;

    private static final JsonMarshaller<UUID> UUID_MARSHALLER = new JsonMarshaller<UUID>();

    @DynamoDBHashKey(attributeName="id")
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }

    // Set<String> holding JSON in DynamoDB
    @DynamoDBAttribute(attributeName="recommendations")
    public Set<String> getRecommendations() {
        if (recommendations != null) {
            Set<String> jsonSet = new HashSet<String>(recommendations.size());
            for (UUID recommendation : recommendations) {
                String json = UUID_MARSHALLER.marshall(recommendation);
                jsonSet.add(json);
            }
            return jsonSet;
        } else {
            return null;
        }
    }
    public void setRecommendations(Set<String> jsonSet) {
        if (jsonSet != null) {
            recommendations = new HashSet<UUID>(jsonSet.size());
            for (String json : jsonSet) {
                UUID recommendation = UUID_MARSHALLER.unmarshall(UUID.class, json);
                recommendations.add(recommendation);
            }
        }
    }

    // convenience methods
    @DynamoDBIgnore
    public UUID convenienceMethod(UUID recommendation) {
        return null;
    }

    // custom object
    public class UUID {

    }
}