読者です 読者をやめる 読者になる 読者になる

日頃の行い

個人的な日頃の行いをつらつら書いてます\\\\ ٩( 'ω' )و ////

ScalaでDynamoDBに接続するためにAWS SDKを利用してみた時の話

ScalaJavaAWS SDKを使ってDynamoDBを利用した時のメモ
本番ではDynamoDBの本物を利用してましたが、ここではDynamoDB Localを利用します。
Java製のAWS SDKScalaから利用しています。

作業したgithubレポジトリはこちらgithub.com

1. DynamoDBローカルのインストール

下記のページからダウンロードして使います。

docs.aws.amazon.com

DynamoDBローカルの準備や起動についてはREADMEを参考にしてください。

https://github.com/tarata/dynamodb-local-for-blog/blob/master/README.md

2. 適当なテーブルの作成

HashキーやらRangeキーなど設定がありますが、それらについては下記のページを参考にしてください。
今回はHashキーをidにしたテーブル「users」を作成します。

qiita.com

Credentialは $HOME/.aws/credential のkeyを利用しています。

テーブル作成に利用するクラス

これで設定おkです
この後UserモデルだけJavaで書きました
なぜなら、Scala力が足りないからです。

Userモデル

3. テーブルのデータを突っ込む部分と取得する部分

データを突っ込む部分

データを取得する部分

たったこれだけでDynamoDBへのORマッパー的なことが出来ます。
アノテーションで出来て便利ですね!!11
4. ハマったところに続く...


ちなみに、jsonを保存したりしたい場合は以下のサイトが参考になります。
Using Custom Marshallers to Store Complex Objects in Amazon DynamoDB - AWS Developer Blog - Java

4. ハマったところ

com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMappingException: Failed to instantiate new instance of class
	at com.amazonaws.services.dynamodbv2.datamodeling.ConversionSchemas$StandardItemConverter.createObject(ConversionSchemas.java:629)
	at com.amazonaws.services.dynamodbv2.datamodeling.ConversionSchemas$StandardItemConverter.unconvert(ConversionSchemas.java:420)
	at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.privateMarshallIntoObject(DynamoDBMapper.java:690)

Failed to instantiate new instance of class は主に Class.newInstance() を実行した時に出るエラーメッセージみたいですね。
Java力が足りなくてわかりませんでした。
Scala力も足りないしDynamoDB力も足りないので、切り分けが出来なかったのですが、普通にググったら普通にわかってあれがあれでした。

このOR Mapperはデータを取得した際に、今回で言えば、 **User.newInstance()** を実行し、
その後setterでデータを入力しているようです。
なので、引数なしコンストラクタがないと死にます←

IntelliJが「これ使ってないよ!使ってないのに消さないの??」
って言ってきたので消したら動きませんでした。
怖いですね、リフレクションメソッド

5. 最終的にどうしたか

正直Mapperは必要がないので、findAllとsaveといメソッドを持ったRepositoryを定義しました。

UserRepository.scala

UserConversions.scala

こうすればアノテーション地獄にもならずかけます。
そんな複雑なことしないので、ORマッパーを使うよりリポジトリを定義して使ってあげるほうが楽そうです。