How to make MongoCollectoin return java.sql.Timestamp?

半城伤御伤魂 提交于 2019-12-12 02:19:36

问题


Basing on https://jira.mongodb.org/browse/JAVA-1741 I'm trying to implement and use TimestampCodec, and expect that decode() is used when reading MongoCollection, but for some reason decode() is not executed and so IsoDate value from database is converted to java.util.Date instead of expected java.sql.Timestamp.

What is the right way to make my TimestampCodec.decode() be used when retrieving MongoCollection?

I have the following, but it fails with java.lang.AssertionError: expected:<class [Ljava.sql.Timestamp;> but was:<class java.util.Date>

@Test
public void testTimestamp() {
    Map<BsonType, Class<?>> replacements = new HashMap<BsonType, Class<?>>();
    replacements.put(BsonType.DATE_TIME, Timestamp.class);
    BsonTypeClassMap bsonTypeClassMap = new BsonTypeClassMap(replacements);
    DocumentCodecProvider documentCodecProvider =
            new DocumentCodecProvider(bsonTypeClassMap);
    CodecRegistry codecRegistry = CodecRegistries.fromRegistries(
    CodecRegistries.fromCodecs(
            new TimestampCodec()),
            MongoClient.getDefaultCodecRegistry(),
            CodecRegistries.fromProviders(documentCodecProvider));
    Builder optionsBuilder = new MongoClientOptions.Builder();
    optionsBuilder.codecRegistry(MongoCodecs.codecRegistry());
    MongoClientOptions options = optionsBuilder.build();
    MongoClient mongo = new MongoClient(new ServerAddress(), options);
    MongoDatabase db = mongo.getDatabase("mydb");
    MongoCollection<Document> collection = db.getCollection("test");
    try {
        collection.insertOne(new Document("date", new Timestamp(new Date().getTime())));
        assertEquals(Timestamp[].class, collection.find().first().get("date").getClass());
    } finally {
        collection.drop();
        mongo.close();
    }
}

回答1:


Beside minor mistakes, solution is to change order of codec registries, so that MongoClient.getDefaultCodecRegistry() is the last one.

Correct code is:

@Test
public void testTimestamp() {
    Map<BsonType, Class<?>> replacements = new HashMap<BsonType, Class<?>>();
    replacements.put(BsonType.DATE_TIME, Timestamp.class);
    BsonTypeClassMap bsonTypeClassMap = new BsonTypeClassMap(replacements);
    DocumentCodecProvider documentCodecProvider =
            new DocumentCodecProvider(bsonTypeClassMap);
    CodecRegistry codecRegistry = CodecRegistries.fromRegistries(
            CodecRegistries.fromCodecs(
                    new TimestampCodec()),
            CodecRegistries.fromProviders(documentCodecProvider),
            MongoClient.getDefaultCodecRegistry());
    Builder optionsBuilder = new MongoClientOptions.Builder();
    optionsBuilder.codecRegistry(codecRegistry);
    MongoClientOptions options = optionsBuilder.build();
    MongoClient mongo = new MongoClient(new ServerAddress(), options);
    MongoDatabase db = mongo.getDatabase("mydb");
    MongoCollection<Document> collection = db.getCollection("test");
    try {
        collection.insertOne(new Document("date", new Timestamp(new Date().getTime())));
        assertEquals(Timestamp.class, collection.find().first().get("date").getClass());
    } finally {
        collection.drop();
        mongo.close();
    }
}


来源:https://stackoverflow.com/questions/33419894/how-to-make-mongocollectoin-return-java-sql-timestamp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!