2014-11-23 134 views
16

我有以下类,我想在MongoDB中存储使用Spring数据存储Java 8即时为BSON日期使用SpringData-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值类型;从Spring 4和JDK 8到JSR-310 java.time类型。

我使用Spring 4.1.1和JDK 8,所以我期望它适用于Instant。然而,这里就是实际存储:

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

如果我写,并从即时注册自定义转换器在this answer解释日期一样,然后它工作,但我想避免这种情况,因为我相信一定有一个更好的方法。

在春源代码进一步挖掘后,我发现了以下类Jsr310DateTimeFormatAnnotationFormatterFactory看起来有前途的:与使用JSR-310 java.time包在JDK 8.

的DateTimeFormat注解

格式字段

其来源不参考Instant,但它确实引用了OffsetTime和LocalTime。即使如此,当我在我的示例中将Instant更改为OffsetDateTime时,仍然将其存储为复合对象而不是ISODate。

缺什么?

回答

4

我认为问题在于你试图使用Instant作为一个时间。从概念上讲,这是时间轴上的一点,并不意味着格式化。我们知道,Java 8时间API是在joda时间开发的(并且参与了joda时间的开发人员)。下面是从约达时间Instant评论:

即时的应用于表示时间 一个点而不管任何其他因素,如时间上或时区。

这就是为什么没有格式化org.joda.time.InstantJodaDateTimeFormatAnnotationFormatterFactory它出现在Spring 3.0以来。并且它也没有在Jsr310DateTimeFormatAnnotationFormatterFactory

没有实现所以,你应该使用自定义转换器或考虑使用更适合的类。

+0

似乎合理。但是'Jsr310DateTimeFormatAnnotationFormatterFactory'中有'OffsetDateTime',但它的格式也不是 – Vic 2014-12-02 08:39:13

+0

@Vic DateTimeFormat注释不负责格式化存储(mongodb)。它在应用程序级别上工作(例如,在JSP页面上进行格式化)。有用于将数据转换为适当类型的转换器。我发现Java 8时间API只有'ZonedDateTimeToCalendarConverter'。那么你可以尝试使用ZonedDateTime吗? – retroq 2014-12-02 09:49:08