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 {
}
}