4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

spring-data-dynamodbを使ったときのエラー回避のメモ

Last updated at Posted at 2017-02-27

Spring Data DynamoDBを使う

Spring Data DynamoDBの使い方は、GitHubのプロジェクトページをご参照ください。

バージョンではまる

spring-data-dynamodb 4.5.0だと、上記公式ページのチュートリアルどおりに書いてもなぜかエラーが出るので、Compatibilityの表を見て、同じくSpring Framework4.3以降で使える、4.3.1まで下げると、エラーがでなくなりました。

4.3.1だと発生せず、4.4.x以降だと発生するエラーは下記の通りで

console
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.socialsignin.spring.data.dynamodb.repository.support.DynamoDBRepositoryFactoryBean]: No default constructor found; nested exception is java.lang.NoSuchMethodException: org.socialsignin.spring.data.dynamodb.repository.support.DynamoDBRepositoryFactoryBean.<init>()
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:85)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1102)
	... 47 more
Caused by: java.lang.NoSuchMethodException: org.socialsignin.spring.data.dynamodb.repository.support.DynamoDBRepositoryFactoryBean.<init>()
	at java.lang.Class.getConstructor0
	at java.lang.Class.getDeclaredConstructor(Class.java:2178)
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:80)
	... 48 more

Publicコンストラクタが無いために見えるのですが、チュートリアルどおりだとrepositoryはinterfaceで、

XxxRepository.java
@EnableScan
public interface XxxRepository extends CrudRepository<Xxx, String> {

実装クラスはSpring framework側でproxyのインスタンスが動的に作成されるはずなので、どう回避したものやら…
#ご存知の方がいらっしゃいましたら、教えて頂けると助かります

エラー「No field annotated with interface org.springframework.data.annotation.Id found!」が発生する

しかし、お試しでハッシュキーだけ使って書くと動作したのに、ハッシュキーとレンジキーの両方をアノテーションで指定すると、途端にこのようなエラーが発生します。

これにはまった方は、こちらのissue報告および回避策のソース[1][2]をご参照ください。
[追記]最終的なガイドのページはこちらのようです。

僕もこれで、動作するようになりました。

ポイントは『ハッシュキーとレンジキーを格納するIDクラスを作成する』ということです。

細かい規則は下記です。

  • IDクラスは、Serializableを実装する
  • IDクラスには、ハッシュキーとレンジキーのフィールドと、getter/setterを作成する
  • IDクラスのハッシュキーのgetterに@DynamoDBHashKeyを、レンジキーのgetterに@DynamoDBRangeKeyを付与する
  • 元のEntityクラスは、IDクラスにSpringの@IDアノテーションを付与する
  • Entityクラスに、ハッシュキーとレンジキーのgetter/setterを作成し、IDクラスのgetter/setterを呼出す
  • このとき、Entityクラスのフィールドにハッシュキーとレンジキーそのものがあるかどうかは特に気にしない
  • Entityクラスのハッシュキーのgetterに@DynamoDBHashKeyを、レンジキーのgetterに@DynamoDBRangeKeyを付与する。これはIDクラスのアノテーションと重複する(けど、気にしない)

直接記載はされていませんが、忘れやすいこととして

  • RepositoryクラスのGenerics内のIDのクラスは、上記で作製したIDクラスを指定する

#サンプルソースだと、ハッシュキーがThreadIdクラスという少し特殊なクラスなので、Marshallerが定義されていますが、Stringなどがハッシュキーの場合は、@DynamoDBMarshallingの指定は無くて大丈夫です。

こちらのisuue報告でのコメントによると、
Spring-DataとAWS-SDKでのアノテーションがそれぞれあり、Spring-Data-Dynamodbはそれら2つの統合作業なので、どうしてもこのような(アノテーション関連の)エラーが出てしまう、それは驚きではないんだけれども、ということでした。

振り返ると、いろんなページのチュートリアル[1][2][3][4]で、Hashキーだけのサンプルが多いんですが、そういうことなんでしょうかね…

今後

DynamoDBMapperでもアノテーションは実現できているし、spring-data-dynamodbを使って悩まし過ぎるときは、DynamoDBMapperを直接使う(つまり、AWS SDKだけ使う)ようにしてもいいかなと考えています。

以上です。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?