Cannot serialize LocalDate in Mongodb

前端 未结 3 465
闹比i
闹比i 2021-01-13 07:38

I am using the java 8 java.time.LocalDate to parse around dates.

But trying to insert a LocalDate object to mongodb. I get errors in the java driver:



        
相关标签:
3条回答
  • 2021-01-13 07:42

    Unfortunately, the MongoDB driver uses the java.util.Date type, see the docs here

    So you have to convert your LocalDate to a Date instance first, for example:

    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);
    

    I would suggest using something like Morphia or Jongo to wrap the MongoDB driver though, as you can register global mappers to implicitly do these conversions on the fly, so that you can use LocalDate, etc, in your domain model

    0 讨论(0)
  • 2021-01-13 07:49

    For anyone coming across this question, the following converter would get someone started in the right direction. This TypeConverter converts between Date and LocalDateTime (Making this distinction because the OP specifically asked about LocalDate).

    Add the following converter to Morphia as follows:

    morphia.getMapper().getConverters().addConverter(new LocalDateTimeConverter());
    

    Here is the converter class:

    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()));
        }
    }
    
    0 讨论(0)
  • 2021-01-13 07:51

    As Oliver Gierke mentions here

    This datatype is not supported yet. I hope this will be available soon.

    0 讨论(0)
提交回复
热议问题