java – DynamoDBMapper仅在唯一时保存项目

前端之家收集整理的这篇文章主要介绍了java – DynamoDBMapper仅在唯一时保存项目前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图根据两个不同列的组合将表中的项保持唯一.

我有一个instanceId和imageId列(以及其他)并基于StackoverflowAWS Forums上的几个帖子,下面应该有效吗?

public void saveUnique(Server server) {
    DynamoDBSaveExpression saveExpression = new DynamoDBSaveExpression();
    Map<String,ExpectedAttributeValue> expectedAttributes =
        ImmutableMap.<String,ExpectedAttributeValue>builder()
            .put("instanceId",new ExpectedAttributeValue(false))
            .put("imageId",new ExpectedAttributeValue(false))
            .build();
    saveExpression.setExpected(expectedAttributes);
    saveExpression.setConditionalOperator(ConditionalOperator.AND);
    try {
        mapper.save(server,saveExpression);
    } catch (ConditionalCheckFailedException e) {
        //Handle conditional check
    }
}

但是,每次我尝试保存重复项(相同的instanceId和imageId)时,它都会成功保存到数据库中.

我在这里错过了什么?

编辑R.E notionquest答案

更新到下面的答案.

我有一个每分钟运行一次API的工作. API的响应表示为服务器POJO.服务器具有名为instanceId的属性.

我想确保如果具有该instanceId的服务器已经在数据库中,请不要保存它.

Server对象具有另一个id属性,该属性被设置为表主键.

public void saveUnique(Server server) {
    DynamoDBSaveExpression saveExpression = new DynamoDBSaveExpression();

    Map<String,ExpectedAttributeValue> expected = new HashMap<>();
    expected.put("instanceId",new ExpectedAttributeValue(new AttributeValue(server.getInstanceId())).withComparisonOperator(ComparisonOperator.NE));
    saveExpression.setExpected(expected);

    try {
        mapper.save(server,saveExpression);
    } catch (ConditionalCheckFailedException e) {
        LOGGER.info("Skipped saving as not unique...");
    }
}

代码将一次又一次地保存Server对象,但不会抛出异常.

服务器POJO

@DynamoDBTable(tableName = "Servers")
public class Server {

    @Id
    private String id = UUID.randomUUID().toString();

    @DynamoDBTypeConvertedJson
    private Task task;

    @DynamoDBAttribute(attributeName = "instanceId")
    private String instanceId;

    public Server() {
    }

    @DynamoDBHashKey
    public String getId() {
        return id;
    }

    // other standard getters and setters
}

解决方法

如果我正确理解了这个问题,那么您希望确保不是哈希键的字段的唯一性.

(我不确定为什么你不使用instanceId作为Servers表的哈希键,我想你有理由这样做).

我的回答:看起来如果不使用辅助表就无法做到这一点.

这是您现有的Servers表:

+----------------------------------------------+
|                 Servers                      |   
+----------------------------------------------+
| * id            the hash key                 |
| * instanceId    non-key field,must be unique|
|                                              |
| * ...                                        |
| * other fields                               |
| * ...                                        | 
+----------------------------------------------+

我将创建一个使用instanceId作为哈希键的附加表:

+----------------------------------------------+
|                 Instance                     |   
+----------------------------------------------+
| * instanceId    the hash key                 |
+----------------------------------------------+

拥有这样的表,在将记录保存到服务器之前,您必须这样做
首先通过向Instance添加记录(putItem)来确保instanceId值是唯一的,提供一个ConditionExpression,如attribute_not_exists(instanceId).

并且只有在没有ConditionalCheckFailedException错误的情况下完成put操作时,您才可以继续将记录添加到Servers中.

如果您想基于两个字段instanceId和imageId的组合来确保服务器中记录的唯一性,
而不是只是instanceId使用这些字段的连接值作为aux表中的单个字段:

+----------------------------------------------+
|               Instance_Image                 |   
+----------------------------------------------+
| * instanceId_imageId   the hash key          |
+----------------------------------------------+

猜你在找的Java相关文章