尝试使用DynamoDBMapper时出现异常:HASH键

时间:2018-01-08 18:29:35

标签: database hash nosql amazon-dynamodb primary-key

我有一个DynamoDB表,主键(id:integer)和辅助键(dateTo:String)。我创建了一个使用DynamoDBMapper的类:

@DynamoDBTable(tableName="MyItems"
public class MyItemsMapper {
    private int id;
    private String dateTo;
    private String name;

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

    @DynamoDBAttribute(attributeName="dateTo")
    public void setDateTo(String dateTo) { this.dateTo = dateTo; }
    public String getDateTo() { return dateTo; }

    @DynamoDBAttribute(attributeName="name")
    public void setName(String name { this.name = name; }
    public String getName() { return name; }

    public boolean saveItem(MyItemsMapper item) {
      try {
        DynamoDBMapper mapper = new DynamoDBMapper(client); //<-- This connects to the DB. This works fine.
        item.setId(generateUniqueNumber()); //<-- This generates a unique integer. Also seems to work fine.
        mapper.save(item);
        logger.info("Successfully saved item. See info below.");
        logger.info(item.toString());
        return true;
      } catch (Exception e) {
        logger.error("Exception while trying to save item: " + e.getMessage());
        e.printStackTrace();
        return false;
      }
    }
}

然后我有一个使用上面的bean的管理器类,如下所示:

public class MyManager {
    public boolean recordItem(
            int id,
            String dateTo,
            String name,
    ) {
        MyItemsMapper myItemsMapper = new MyItemsMapper();
        myItemsMapper.setId(id);
        myItemsMapper.setDateTo(dateTo);
        myItemsMapper.setName(name);
        myItemsMapper.saveItem(myItemsMapper);
    }
}

我在JUnit测试中运行管理器类:

public class MyManagerTest {
    @Test
    public void saveNewItemTest() {
        MyManager myManager = new MyManager();
        myManager.recordItem(1234567, "2018-01-01", "Anthony");
    }
}

当我通过运行我的JUnit测试时通过我的经理使用上面的saveItem方法时,我收到以下错误:

com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMappingException: MyItemsMapper; no mapping for HASH key

不确定它与什么有关,因为我的表格肯定有一个主键,而且我的辅助键也总是有值。

如何让它发挥作用?

更多信息:

值得注意的是,我可以通过Item object将数据记录到我的DynamoDB表中。如果我执行以下操作,我的数据将记录到数据库中:

DynamoDB dynamoDB = new DynamoDBClient().connectToDynamoDB(); //<-- 
Connection. Works fine.
Table table = dynamoDB.getTable("MyItems");
item.withPrimaryKey("id", 1234567);
item.withString("dateTo", "2018-01-01");
item.withString("name", "Anthony");
PutItemOutcome outcome = table.putItem(item);

但是,我正在尝试使用DynamoDBMapper,因为我读到它是一种更有条理,更好的访问数据的方法。

1 个答案:

答案 0 :(得分:1)

我不确定这是否会导致问题,但您正在创建myItemsMapper对象,然后将对此对象的引用传递给自身。

我建议删除你的saveItem方法。 MyItemsMapper类应该是一个普通的旧java对象。然后使MyManager像这样

public class MyManager {
    public boolean recordItem(
            int id,
            String dateTo,
            String name,
    ) {
        MyItemsMapper myItemsMapper = new MyItemsMapper();
        myItemsMapper.setId(id);
        myItemsMapper.setDateTo(dateTo);
        myItemsMapper.setName(name);
        DynamoDBMapper mapper = new DynamoDBMapper(client); 
        mapper.save(myItemsMapper);
    }
}

如果你特别想保持saveItem方法,就像这样

public boolean saveItem() {
  try {
    DynamoDBMapper mapper = new DynamoDBMapper(client);
    mapper.save(this);
    logger.info("Successfully saved item. See info below.");
    logger.info(this.toString());
    return true;
  } catch (Exception e) {
    logger.error("Exception while trying to save item: " + e.getMessage());
    e.printStackTrace();
    return false;
  }
}

然后在MyManager中

    MyItemsMapper myItemsMapper = new MyItemsMapper();
    myItemsMapper.setId(id);
    myItemsMapper.setDateTo(dateTo);
    myItemsMapper.setName(name);
    myItemsMapper.saveItem();