问题
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