我有以下类,我希望使用Spring数据将其存储在MongoDB中
@Document()
public class Tuple2<T extends Enum<T>> {
@Id
private String id;
@Indexed
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
private final Instant timeCreated;
...
}
DateTimeFormat注释javadoc声明:
声明应将字段格式化为日期时间。支持按样式模式、ISO日期时间模式或自定义格式模式字符串设置格式。可以应用于java.util.Date、java.util.Calendar、java.long.Long、Joda-Time值类型;从Spring4和JDK8开始,也可以应用于JSR-310 java.time类型。
我使用的是Spring4.1.1和JDK8,所以我希望它适用于Instant
。然而,下面是实际存储的内容:
"timeCreated" : {
"seconds" : NumberLong(1416757496),
"nanos" : 503000000
}
如果我像this answer中解释的那样编写并注册从即时到日期的自定义转换器,那么它就可以工作,但是我想避免这种情况,因为我相信一定有更好的方法。
在进一步挖掘Spring源代码后,我发现了以下类Jsr310DateTimeFormatAnnotationFormatterFactory
,它看起来很有前途:
使用JDK8中的DateTimeFormat -310JSR- java.time包格式化使用JSR-310注释的字段。
它的“source”没有引用Instant
,但它引用了OffsetTime和LocalTime。即使如此,当我在示例中将Instant更改为OffsetDateTime时,它仍然存储为复合对象,而不是ISODate。
遗漏了什么?
发布于 2014-12-01 04:12:21
我认为问题在于您试图使用Instant
作为一个时间。从概念上讲,它是时间线上的一个点,并不意味着格式化。
正如我们所知,Java 8 time API的开发着眼于joda-time (以及joda-time的开发人员)。以下是来自joda-time Instant
的评论
即时应用于表示时间点,而不考虑任何其他因素,如年表或时区。
这就是为什么在JodaDateTimeFormatAnnotationFormatterFactory
中不能对org.joda.time.Instant
进行格式化的原因,Spring从3.0版开始就出现了。而且它不是在Jsr310DateTimeFormatAnnotationFormatterFactory
中实现的
因此,您应该使用自定义转换器或考虑使用更合适的类。
发布于 2020-04-15 12:41:05
我对所有时间戳类型的数据都使用instant,就像您创建的timecreated一样。如果它是针对最终用户的,比如日历条目,那么LocalDateTime的效果会更好,但它们都可以使用ISO格式的时间字符串创建。在某些情况下,需要格式化时间点数据(日期或即时)以实现可读性或序列化/可移植性。
因此,如果有人在当前的MongoDB版本中遇到这个问题,要回答这个问题,您不需要在代码中做任何事情。我使用init脚本初始化了mongodb容器中的一些数据。我使用的是ISODate格式。
"timestamp": ISODate("2020-03-17T13:50:56.618Z")
我还有一个Spring Boot2和Spring Data应用程序。文档完全支持它。https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mapping-conversion
https://stackoverflow.com/questions/27091418
复制相似问题