本文介紹了使用SpringData-MongoDB將Java 8 Instant存儲為bson日期的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧!
問題描述
我希望使用Spring數(shù)據(jù)將以下類存儲在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聲明:
聲明字段應(yīng)格式化為日期時間。
支持按樣式模式、ISO日期時間模式或自定義格式模式字符串進(jìn)行格式設(shè)置。可應(yīng)用于java.util.Date、java.util.Calendar、java.Long.Long、Joda-Time值類型;從Spring4和JDK 8開始,也可應(yīng)用于JSR-310的java.time類型。
我使用的是Spring4.1.1和JDK8,所以我希望它適用于Instant
。然而,以下是實際存儲的內(nèi)容:
"timeCreated" : {
"seconds" : NumberLong(1416757496),
"nanos" : 503000000
}
如果我像this answer中解釋的那樣編寫并注冊從Instant到Date的自定義轉(zhuǎn)換器,那么它就可以工作,但是我想避免這種情況,因為我相信肯定有更好的方法。
在進(jìn)一步挖掘Spring源代碼后,我發(fā)現(xiàn)了以下類Jsr310DateTimeFormatAnnotationFormatterFactory
,它看起來很有前途:
使用JDK 8中的JSR-310 java.time包設(shè)置用DateTimeFormat批注批注的字段的格式。
其”源”未引用Instant
,但它確實引用了OffsetTime和LocalTime。即使如此,當(dāng)我在我的示例中將Instant更改為OffsetDateTime時,它仍然存儲為復(fù)合對象,而不是ISODate。
缺少什么?
推薦答案
我認(rèn)為問題在于您嘗試使用的時間Instant
。從概念上講,它是時間線上的一個點,并不意味著格式化。
正如我們所知,Java 8 Time API的開發(fā)著眼于joda-time(并關(guān)注joda-time的開發(fā)人員)。以下是來自joda-timeInstant
的評論:
應(yīng)使用Instant來表示時間點
不考慮任何其他因素,如年表或時區(qū)。
這就是為什么JodaDateTimeFormatAnnotationFormatterFactory
中的org.joda.time.Instant
沒有格式化的可能,這是從3.0版開始出現(xiàn)在Spring中的。而且在Jsr310DateTimeFormatAnnotationFormatterFactory
中也沒有實現(xiàn)
因此,您應(yīng)該使用自定義轉(zhuǎn)換器或考慮使用更合適的類。
這篇關(guān)于使用SpringData-MongoDB將Java 8 Instant存儲為bson日期的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,