Java 无法序列化Mongodb中的LocalDate
我正在使用Java8java.time.LocalDate来解析日期 但是尝试向mongodb插入LocalDate对象。我在java驱动程序中发现错误:Java 无法序列化Mongodb中的LocalDate,java,json,mongodb,scala,Java,Json,Mongodb,Scala,我正在使用Java8java.time.LocalDate来解析日期 但是尝试向mongodb插入LocalDate对象。我在java驱动程序中发现错误: private def writeData(measure: DBCollection, installation: Int, date: String, dates: ListBuffer[LocalDate], values: ListBuffer[BigDecimal], validated: B
private def writeData(measure: DBCollection, installation: Int, date: String, dates: ListBuffer[LocalDate],
values: ListBuffer[BigDecimal], validated: Boolean, overwrite: Boolean) {
val timeValues: BasicDBList = new BasicDBList
var i = 0
while ( i < dates.size ) {
val obj: BasicDBObject = new BasicDBObject("time", dates(i))
obj.put("value", values(i).toString())
timeValues.add(obj)
i += 1
}
if ( debug ) System.out.println("Storedata: " + timeValues.toString) <-- error here
private def writeData(度量值:DBCollection,安装:Int,日期:String,日期:ListBuffer[LocalDate],
值:ListBuffer[BigDecimal],已验证:布尔值,覆盖:布尔值){
val时间值:BasicDBList=新的BasicDBList
变量i=0
而(i
此数据类型尚不受支持。我希望很快可以使用。不幸的是,MongoDB驱动程序使用java.util.Date
类型,请参阅文档
因此,您必须首先将LocalDate转换为日期实例,例如:
MongoClient mongoClient = new MongoClient("localhost", 27017);
DB db = mongoClient.getDB("test");
DBCollection coll = db.getCollection("testcol");
LocalDate ld = LocalDate.now();
Instant instant = ld.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant();
Date date = Date.from(instant);
BasicDBObject doc = new BasicDBObject("localdate", date);
coll.insert(doc);
我建议使用类似或的东西来包装MongoDB驱动程序,因为您可以注册全局映射程序来动态隐式地进行这些转换,这样您就可以在域模型中使用LocalDate等。对于遇到这个问题的任何人,下面的转换程序都会让人朝着正确的方向开始>TypeConverter
在日期
和本地日期时间
之间进行转换(进行此区分是因为OP专门询问了LocalDate)
将以下转换器添加到Morphia,如下所示:
morphia.getMapper().getConverters().addConverter(new LocalDateTimeConverter());
以下是转换器类:
public class LocalDateTimeConverter extends TypeConverter implements SimpleValueConverter {
public LocalDateTimeConverter() {
// TODO: Add other date/time supported classes here
// Other java.time classes: LocalDate.class, LocalTime.class
// Arrays: LocalDateTime[].class, etc
super(LocalDateTime.class);
}
@Override
public Object decode(Class<?> targetClass, Object fromDBObject, MappedField optionalExtraInfo) {
if (fromDBObject == null) {
return null;
}
if (fromDBObject instanceof Date) {
return ((Date) fromDBObject).toInstant().atZone(ZoneOffset.systemDefault()).toLocalDateTime();
}
if (fromDBObject instanceof LocalDateTime) {
return fromDBObject;
}
// TODO: decode other types
throw new IllegalArgumentException(String.format("Cannot decode object of class: %s", fromDBObject.getClass().getName()));
}
@Override
public Object encode(Object value, MappedField optionalExtraInfo) {
if (value == null) {
return null;
}
if (value instanceof Date) {
return value;
}
if (value instanceof LocalDateTime) {
ZonedDateTime zoned = ((LocalDateTime) value).atZone(ZoneOffset.systemDefault());
return Date.from(zoned.toInstant());
}
// TODO: encode other types
throw new IllegalArgumentException(String.format("Cannot encode object of class: %s", value.getClass().getName()));
}
}
公共类LocalDateTimeConverter扩展TypeConverter实现SimpleValueConverter{
公共LocalDateTimeConverter(){
//TODO:在此处添加其他日期/时间支持的类
//其他java.time类:LocalDate.class、LocalTime.class
//数组:LocalDateTime[].class等
super(LocalDateTime.class);
}
@凌驾
公共对象解码(类targetClass、对象fromDBObject、MappedField optionalExtraInfo){
if(fromDBObject==null){
返回null;
}
if(fromDBObject instanceof Date){
返回((日期)fromDBObject.toInstant().atZone(ZoneOffset.systemDefault()).toLocalDateTime();
}
if(LocalDateTime的fromDBObject实例){
从dbobject返回;
}
//TODO:解码其他类型
抛出新的IllegalArgumentException(String.format(“无法解码类:%s的对象”,fromDBObject.getClass().getName());
}
@凌驾
公共对象编码(对象值,MappedField optionalExtraInfo){
如果(值==null){
返回null;
}
if(值instanceof Date){
返回值;
}
if(LocalDateTime的instanceof值){
ZonedDateTime Zone=((LocalDateTime)值).atZone(ZoneOffset.systemDefault());
返回日期.from(zone.toInstant());
}
//TODO:对其他类型进行编码
抛出新的IllegalArgumentException(String.format(“无法对类:%s的对象进行编码”,value.getClass().getName());
}
}
感谢您提供有关Morphia和Jongo的参考资料。我一定会查找这些资料。我应该指出,在这一点上,对于3.x驱动程序,我发现对Morphia和Jongo的需求没有那么重要,因为对于您可能需要的少数额外类型,使用Jackson/Jackson4Bson插入自定义Serlializer要简单得多