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

Mongo driver 3 codec facility might not be used [DATAMONGO-1175] #2094

Closed spring-projects-issues closed 5 years ago

spring-projects-issues commented 9 years ago

Alexander Bagerman opened DATAMONGO-1175 and commented

It appears that to use new Codec facility introduced with java driver 3 one has to operate with org.bson.Document rather than com.mongodb.BasicDBObject.

It looks like 1.7 is still using DBObject which is a problem for UUID serialization in "proper" rather than the "legacy" format as I was trying to do.

Just confirmed that non-default codecs are ignored when serializing objects via mongotemplate but used when done through direct java driver api.

Thanks Alex


Affects: 1.7 RC1 (Fowler)

Reference URL: https://groups.google.com/forum/#!topic/mongodb-user/ZJKQpMpCMU4

Issue Links:

2 votes, 7 watchers

spring-projects-issues commented 9 years ago

Alexander Bagerman commented

see comments here regarding DB/DBCollection do not use the codec registry : https://jira.mongodb.org/browse/JAVA-1675

spring-projects-issues commented 9 years ago

Christoph Strobl commented

Thanks Alexander Bagerman for bringing this up - For the Fowler release we plan to stick with the 2.x line of mongo-java-driver, while allow usage of generation 3 as well. A full upgrade (inlcuding the adaption of org.bson...) is planned for Gosling

spring-projects-issues commented 9 years ago

Steven Pearce commented

So with the release of Gosling today, I thought try and get UUID serialization to use the codecs. I used mongo-java-driver v3.0.2 with spring-data-mongodb 1.8

Bean Creation

  @Bean
  public MongoClient mongoClientBean() {

    MongoClientOptions.Builder builder = MongoClientOptions.builder();
    CodecRegistry codecRegistry = fromRegistries(fromCodecs(new UuidCodec(UuidRepresentation.STANDARD)), MongoClient.getDefaultCodecRegistry());
    builder.codecRegistry(codecRegistry);

    return new MongoClient("localhost:27017", builder.build());
  }

  @Bean
  public MongoTemplate mongoTemplateBean() throws Exception {
    return new MongoTemplate(mongoClientBean(), "d1");
  }

Tests

public class MongoTest {

// ApplicationContext code omitted for brevity
  public static void main(String[] args) {

    // Uses UuidRepresentation.STANDARD
    mongoClient.getDatabase("d1").getCollection("c1").insertOne(new Document("testUUID", UUID.randomUUID()));

    // Reverts to using UuidRepresentation.JAVA_LEGACY
    mongoTemplate.save(new TSTUUID(), "c1");

  }

  private static class TSTUUID {
    private UUID testUUID = UUID.randomUUID();
  }
}

The Results are

{ "_id" : ObjectId("55e60d5237cefc87a4c877ea"), "testUUID" : BinData(4,"+q2+Xoo4S5yVON30WF57Cw==") }
{ "_id" : ObjectId("55e60d5237cefc87a4c877eb"), "_class" : "cli.MongoTest$TSTUUID", "testUUID" : BinData(3,"fEMg28Tr22NtkUSxBQNvpw==") }

Using mongoClient directly works great and I get Standard UUID serialisation, but using the MongoTemplate Wrapper or creating the client with MongoClientFactoryBean (not shown) does not, as it continues to use the legacy UUID serialisation

I've stepped through quite a big of code on your side and mongodb side, it appears that MongoTemplate doesn't use the codecs in the client and eventually calls the mongodb driver with no Encoder, so it calls

MongoClient.getDefaultCodecRegistry()

again and creates its own default set which uses the Legacy UUID serialisation.

Hope I've made sense, and have I missed something that makes this a non-problem?

spring-projects-issues commented 8 years ago

Michael commented

Are there any plans to resolve this issue?

spring-projects-issues commented 8 years ago

Christoph Strobl commented

There's a feature branch available at github:/issue/DATAMONGO-1176 that will merge with the effords towards adding support for the reactive driver (DATAMONGO-1444). The switch to the document API includes a lot of breaking changes and will therefore not be included in the 1.x line.

As a workaround you can try the approach outlined in gist:/7299a1e28aee18af14ff