ZonedDateTime avec Spring Data MongoDB

ZonedDateTime avec Spring Data MongoDB

1. Vue d'ensemble

Le moduleSpring Data MongoDB améliore la lisibilité et la convivialité lors de l'interaction avec une base de données MongoDB dans les projets Spring.

Dans ce didacticiel, nous allons nous concentrer sur la manière de gérer les objets JavaZonedDateTime lors de la lecture et de l’écriture dans une base de données MongoDB.

2. Installer

Pour utiliser le module Spring Data MongoDB, nous devons ajouter la dépendance suivante:


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

La dernière version de la bibliothèque peut être trouvéehere.

Définissons une classe de modèle appeléeAction (avec un attributZonedDateTime):

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

    private String description;
    private ZonedDateTime time;

    // constructor, getters and setters
}

Pour interagir avec MongoDB, nous allons également créer une interface qui étend lesMongoRepository:

public interface ActionRepository extends MongoRepository { }

Nous allons maintenant définir un test qui insérera un objetAction dans un MongoDB et affirmera qu'il a été stocké à l'heure correcte. Dans l'évaluation des assertions, nous supprimons les informations sur les nanosecondes car le type MongoDBDate a une précision de quelques millisecondes:

@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));
}

Hors de la boîte, nous allons obtenir l'erreur suivante lors de l'exécution de notre test:

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

Spring Data MongoDB has no ZonedDateTime converters defined. Voyons comment nous pouvons les configurer.

3. Les convertisseurs MongoDB

Nous pouvons gérer les objetsZonedDateTime (sur tous les modèles) en définissant un convertisseur pour lire à partir d'un MongoDB et un pour y écrire.

Pour la lecture, nous convertissons un objetDate en un objetZonedDateTime. Dans l'exemple suivant, nous utilisons lesZoneOffset.UTC puisque l'objetDate ne stocke pas les informations de zone:

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

Ensuite, nous convertissons un objetZonedDateTime en un objetDate. Nous pouvons ajouter les informations de zone à un autre champ si nécessaire:

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

Puisque les objetsDate ne stockent pas de décalage de zone, nous utilisonsUTC dans nos exemples. Avec le sableZonedDateTimeReadConverter lesZonedDateTimeWriteConverter ajoutés auxMongoCustomConversions, notre test passera maintenant.

Une simple impression de l'objet stocké ressemblera à ceci:

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

Pour en savoir plus sur l'enregistrement des convertisseurs MongoDB, nous pouvons nous référer àthis tutorial.

4. Conclusions

Dans cet article rapide, nous avons vu comment créer des convertisseurs MongoDB afin de gérer les objets JavaZonedDateTime.

L'implémentation de tous ces extraits peut être trouvéeover on GitHub.