Spring Data MongoDBでのZonedDateTime

Spring Data MongoDBを使用したZonedDateTime

1. 概要

Spring Data MongoDBモジュールは、SpringプロジェクトでMongoDBデータベースを操作する際の読みやすさと使いやすさを向上させます。

このチュートリアルでは、MongoDBデータベースの読み取りと書き込みを行うときにZonedDateTimeJavaオブジェクトを処理する方法に焦点を当てます。

2. セットアップ

Spring Data MongoDBモジュールを使用するには、次の依存関係を追加する必要があります。


    org.springframework.data
    spring-data-mongodb
    2.1.2.RELEASE

ライブラリの最新バージョンはhereにあります。

ZonedDateTime属性を持つ)Actionというモデルクラスを定義しましょう:

@Document
public class Action {
    @Id
    private String id;

    private String description;
    private ZonedDateTime time;

    // constructor, getters and setters
}

MongoDBとやり取りするために、MongoRepositoryを拡張するインターフェースも作成します。

public interface ActionRepository extends MongoRepository { }

次に、ActionオブジェクトをMongoDBに挿入し、正しい時刻に保存されたことを表明するテストを定義します。 アサーション評価では、MongoDBDateタイプの精度がミリ秒であるため、ナノ秒情報を削除します。

@Test
public void givenSavedAction_TimeIsRetrievedCorrectly() {
    String id = "testId";
    ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);

    actionRepository.save(new Action(id, "click-action", now));
    Action savedAction = actionRepository.findById(id).get();

    Assert.assertEquals(now.withNano(0), savedAction.getTime().withNano(0));
}

テストを実行すると、すぐに次のエラーが表示されます。

org.bson.codecs.configuration.CodecConfigurationException:
  Can't find a codec for class java.time.ZonedDateTime

Spring Data MongoDB has no ZonedDateTime converters defined.それらを構成する方法を見てみましょう。

3. MongoDBコンバーター

MongoDBから読み取るためのコンバーターと、MongoDBに書き込むためのコンバーターを定義することで、(すべてのモデルで)ZonedDateTimeオブジェクトを処理できます。

読むために、DateオブジェクトからZonedDateTimeオブジェクトに変換しています。 次の例では、Dateオブジェクトがゾーン情報を格納しないため、ZoneOffset.UTCを使用します。

public class ZonedDateTimeReadConverter implements Converter {
    @Override
    public ZonedDateTime convert(Date date) {
        return date.toInstant().atZone(ZoneOffset.UTC);
    }
}

次に、ZonedDateTimeオブジェクトからDateオブジェクトに変換します。 必要に応じて、ゾーン情報を別のフィールドに追加できます。

public class ZonedDateTimeWriteConverter implements Converter {
    @Override
    public Date convert(ZonedDateTime zonedDateTime) {
        return Date.from(zonedDateTime.toInstant());
    }
}

Dateオブジェクトはゾーンオフセットを格納しないため、例ではUTCを使用します。 ZonedDateTimeReadConverter ZonedDateTimeWriteConverterMongoCustomConversionsに追加すると、テストに合格します。

保存されたオブジェクトの簡単な印刷は次のようになります。

Action{id='testId', description='click', time=2018-11-08T08:03:11.257Z}

MongoDBコンバーターを登録する方法の詳細については、this tutorialを参照してください。

4. 結論

この簡単な記事では、JavaZonedDateTimeオブジェクトを処理するためにMongoDBコンバーターを作成する方法を見ました。

これらすべてのスニペットの実装はover on GitHubにあります。