spring-projects / spring-data-mongodb

Provides support to increase developer productivity in Java when using MongoDB. Uses familiar Spring concepts such as a template classes for core API usage and lightweight repository style data access.
https://spring.io/projects/spring-data-mongodb/
Apache License 2.0
1.62k stars 1.09k forks source link

Inconsistent Conversion of LocalDate with Documents #3880

Closed scj7t4 closed 1 year ago

scj7t4 commented 3 years ago

I've noticed an inconsistency with how JSR-310 LocalDate is converted to mongo dates when it is put into org.bson.Document.

Reproduction:

Using 'org.springframework.boot:spring-boot-starter-data-mongodb:2.5.6'

package com.example.demo;

import org.bson.Document;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.mongodb.core.MongoTemplate;

import java.time.LocalDate;
import java.util.List;

import static org.hamcrest.MatcherAssert.assertThat;

@SpringBootTest
class DemoApplicationTests {

    @Autowired
    MongoTemplate mongoTemplate;

    @Test
    void contextLoads() {
        Document document = new Document();
        Document inner = new Document();
        LocalDate date = LocalDate.of(2001, 1, 1);
        document.put("fieldA", date);
        inner.put("fieldB", date);
        document.put("inner", inner);
        mongoTemplate.insert(document, "someCollection");

        List<Document> matched = mongoTemplate.findAll(Document.class, "someCollection");
        Document result = matched.get(0);
        assertThat(result.get("inner", Document.class).get("fieldB"),
                Matchers.equalTo(result.get("fieldA")));
        System.out.println(result.toJson());
    }
}

(Full project repro here: https://github.com/scj7t4/mongodb-localdate-bug)

When I run this test, I expect the values of fieldA and inner.fieldB to be the same. However, they are not equal, fieldA is 2001-01-01T00:00:00 MST as expected, but inner.fieldB is 2000-12-31T17:00:00 MST (7 hours earlier) in my timezone.

I would expect that both values would be the same.

Thanks for all the work you do developing Spring Mongo :)

christophstrobl commented 3 years ago

thanks for pointing that out - good catch.

christophstrobl commented 1 year ago

We've been revisiting this issue and decided to not change the current behaviour as we do consider Document a store native type, that if provided by the user, should in this case only contain values understandable by the driver. Having each and every Document type do another round of potential mapping would also negatively impact runtime behaviour.