田中ブログ

さいたまに住んでいる男です。仕事はSESでプログラムを書いてることが多いです。聖地巡礼、日々の生活、技術的なことを書いていこうと思います。

DynamoDBのDynamoDBMapper(高レベルインターフェース)でmap型(json型)を利用する

技術ネタです。DynamoDBのDynamoDBMapper(高レベルインターフェース)でmap型(json型)を利用するです。(java

DynamoDBの項目の属性をmap(json)にした際に、モデルクラスの当該プロパティをMapとしたらDynamoDBMapperを利用してデータを取得する際に例外が出てしまいました。

以下のように書くと例外が発生。

private Map<String, Object> data;

ちなにみ以下のように書くと例外は出ませんでしたが、Mapの中身に"S"や"N"といった型の内容まで入っていました。

private Map<String, AttributeValue> data;


いろいろぐぐってみたところ変換用クラスを作り、それを利用するように指定することで対処できました。
以下のようなクラスを作成。(javaDocは割愛)

public static class MapConverter implements DynamoDBTypeConverter <Map<String, AttributeValue>, Object> {
    // 保存時の変換
    // @param object 変換元(Map<String, Object>など)
    // @return Map<String, AttributeValue>に変換された値
    @Override
    public Map<String, AttributeValue> convert(Object object) {
        // ItemUtilsはawsのsdkに含まれてるクラス
        return ItemUtils.fromSimpleMap((Map) object);
    }

    // 読み込み時の変換
    // @param 変換元のMap<String, AttributeValue>
    // @return Map<String, Object>
    @Override
    public Object unconvert(Map<String, AttributeValue> map) {
        List<Map<String, AttributeValue>> mapList = new ArrayList<>();
        mapList.add(map);
        // ItemUtilsはawsのsdkに含まれてるクラス
        return ItemUtils.toItemList(mapList).get(0).asMap();
    }
}

モデルのプロパティに以下のようにアノテーションを書く。

@DynamoDBTypeConverted(converter = MapConverter.class)
private Object data;

これだと、Mapの中身に"S"や"N"が入らず期待した通りに動きました。
ちなみに、保存時にこの属性をnullとして保存すると当該属性は登録されず、この属性がnullの項目を読み込むと上記例だとdataはnullが設定されてました。

以上