Stockez Java 8 Instant en tant que date BSON à l’aide de SpringData-MongoDB

J’ai la classe suivante que je veux stocker dans MongoDB en utilisant Spring Data

@Document() public class Tuple2<T extends Enum> { @Id private Ssortingng id; @Indexed @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) private final Instant timeCreated; ... } 

L’annotation DateTimeFormat javadoc déclare:

Déclare qu’un champ doit être formaté en tant que date et heure. Prend en charge le formatage par modèle de style, modèle de date / heure ISO ou chaîne de modèle de format personnalisé. Peut être appliqué aux types de valeur java.util.Date, java.util.Calendar, java.long.Long, Joda-Time; et à partir du spring 4 et du JDK 8, vers les types java.time du JSR-310.

J’utilise Spring 4.1.1 et JDK 8, donc je m’attendrais à ce que cela s’applique à Instant . Cependant, voici ce qui est réellement stocké:

 "timeCreated" : { "seconds" : NumberLong(1416757496), "nanos" : 503000000 } 

Si j’écris et enregistre un convertisseur personnalisé d’Instant à Date comme expliqué dans cette réponse, cela fonctionnera, mais j’aimerais éviter cela, car je suis sûr qu’il doit y avoir un meilleur moyen.

Après avoir approfondi le code source de Spring, j’ai trouvé la classe suivante Jsr310DateTimeFormatAnnotationFormatterFactory qui semble prometteuse:

Formate les champs annotés avec l’annotation DateTimeFormat à l’aide du package JSR-310 java.time dans JDK 8.

Sa source ne fait pas référence à Instant , mais il fait référence à OffsetTime et à LocalTime. Même dans ce cas, lorsque je change Instant en OffsetDateTime dans mon exemple, il est toujours stocké en tant qu’object composite au lieu d’ISODate.

Que manque-t-il?

Je pense que le problème est ce que vous essayez d’utiliser Instant comme un temps. Conceptuellement, c’est un sharepoint la chronologie et cela n’implique pas de formatage.

Comme nous le soaps, l’API Java 8 Time a été développée avec un œil sur joda-time (et avec la partisanerie des développeurs de joda-time). Voici le commentaire de joda-time Instant :

Un instant doit être utilisé pour représenter un point dans le temps, indépendamment de tout autre facteur, tel que la chronologie ou le fuseau horaire.

C’est pourquoi il n’y a aucune possibilité de formatage pour org.joda.time.Instant dans JodaDateTimeFormatAnnotationFormatterFactory paru dans Spring depuis la version 3.0. Et aussi, il n’a pas été implémenté dans Jsr310DateTimeFormatAnnotationFormatterFactory

Donc, vous devez utiliser un convertisseur personnalisé ou envisager d’utiliser une classe plus appropriée.