首页 > 解决方案 > DynamoDB 存储哈希值而不是 json

问题描述

我正在使用 Java 8 和 AWS SDK 1.11 版本。

我有以下表定义:

import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBVersionAttribute;
import com.amazonaws.services.dynamodbv2.datamodeling.encryption.DoNotTouch;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Set;

/**
 * Mapping between a tenant and the roles they defined to access their S3 Attachment buckets.
 */
@DynamoDBTable(tableName = CustomerRoleTenantMapping.TABLE_NAME)
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
@DoNotTouch
public class CustomerRoleTenantMapping {

    public static final String TABLE_NAME = "CustomerRoleTenantMapping";

    /**
     * The identifier of this mapping between the tenant and the roles.
     */
    @DynamoDBHashKey(attributeName = "tenant")
    private String tenant;

    /**
     * The name of the tenant.
     */
    @DynamoDBAttribute(attributeName = "name")
    private String name;

    /**
     * The system that a tenant has allowed to access their S3 Attachment buckets.
     */
    @DynamoDBAttribute(attributeName = "tenantPlatform")
    private String tenantPlatform;

    /**
     * The roles associated to a tenant's S3 Attachment buckets.
     */
    @DynamoDBAttribute(attributeName = "customerRoles")
    private Set<RoleArn> customerRoles;

    @DynamoDBAttribute(attributeName = "version")
    @DynamoDBVersionAttribute
    private Long version;
}

RoleArn 类的定义如下:

import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBDocument;
import com.amazonaws.services.dynamodbv2.datamodeling.encryption.DoNotTouch;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.Setter;

import java.util.Objects;

/**
 * Model for AWS Role ARNs.
 */
@DynamoDBDocument
@Builder
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@DoNotTouch
public class RoleArn {

    /**
     * The Role Arn.
     */
    @NonNull
    @DynamoDBAttribute(attributeName = "arn")
    private String arn;

    /**
     * The description of the role.
     */
    @NonNull
    @DynamoDBAttribute(attributeName = "description")
    private String description;

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof RoleArn) {
            return ((RoleArn) obj).arn.equals(arn);
        }
        return false;
    }

    @Override
    public int hashCode() {
        return Objects.hash(arn);
    }
}

我的问题是,当我尝试在我的 DDB 中存储 CustomerRoleTenantMapping 对象时,RoleArn 不是作为 JSON 而是作为实例的哈希存储的。

仅供参考,我必须在 RoleArn 中实现 equals() 和 hashCode() 的原因是通过仅比较 RoleArns 的两个实例的 arn 属性来避免同一 CustomerRoleTenantMapping 实例中的重复 RoleArns 对象。

我可以做些什么来存储 Set 的 JSON 而不是哈希?

标签: javaamazon-web-servicesamazon-dynamodb

解决方案


默认情况下,DynamoDB 映射器只能转换有限的一组对象:

https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.DataTypes.html

由于您有一组 RoleArn 对象,您将需要使用@DynamoDBTypeConverted注释和定制的 TypeConvertor 类

https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBMapper.ArbitraryDataMapping.html

更新:简而言之,您必须编写另一个类来告诉 DynamoDBmapper 如何将复杂对象转换为 json,然后将 json 字符串取消转换回复杂对象。


推荐阅读