Context
I followed the insructions in mongo.github (related to JAVA-1741) to serialise a field of type OffsetDateTime to Bson String.
Neither the codec not the codecProvider are used during the write operations. The field is then stored in the database as Object:
updatedOn Object:
|
dateTime "2018-04-16 17:11:09.315Z" Date
|
offset "+01:00" String
|
On read operations, the codec is invoked for dateTime and offset fields to deserialise them to an object of type OffsetDateTime. Of course it fails because the codec does not know how to process the offset field.
I have not tested this in Spring Boot 1.x as of yet.
Can't really tell whether this is a configuration problem or a bug. Hence the question "what may be wrong here" instead of a suggestion.
Implementation and configuration details
|
MongoConfig extends AbstractMongoConfiguration
|
@Override
|
public MongoClient mongoClient() {
|
CodecRegistry defaultCodecRegistry = MongoClient.getDefaultCodecRegistry();
|
|
Map<BsonType, Class<?>> replacements = new HashMap<BsonType, Class<?>>();
|
replacements.put(BsonType.DATE_TIME, OffsetDateTime.class);
|
BsonTypeClassMap bsonTypeClassMap = new BsonTypeClassMap(replacements);
|
DocumentCodecProvider documentCodecProvider = new DocumentCodecProvider(bsonTypeClassMap);
|
|
Codec<OffsetDateTime> offsetDateTimeCodec = new OffsetDateTimeCodec();
|
|
CodecRegistry codecRegistry = CodecRegistries.
|
fromRegistries(CodecRegistries.fromCodecs(offsetDateTimeCodec),
|
CodecRegistries.fromProviders(documentCodecProvider),
|
defaultCodecRegistry);
|
|
MongoClientOptions mcs = MongoClientOptions.builder()
|
.codecRegistry(codecRegistry)
|
.build();
|
|
return new MongoClient(new ServerAddress(), mcs);
|
}
|
|
DocumentCodecProvider.java
|
public class DocumentCodecProvider implements CodecProvider {
|
private final BsonTypeClassMap bsonTypeClassMap;
|
|
public DocumentCodecProvider(final BsonTypeClassMap bsonTypeClassMap) {
|
this.bsonTypeClassMap = bsonTypeClassMap;
|
}
|
|
@Override
|
public <T> Codec<T> get(final Class<T> clazz, final CodecRegistry registry) {
|
if (clazz == Document.class) {
|
// construct DocumentCodec with a CodecRegistry and a BsonTypeClassMap
|
return (Codec<T>) new DocumentCodec(registry, bsonTypeClassMap);
|
}
|
|
return null;
|
}
|
}
|
|
OffsetDateTimeCodec.java
|
public class OffsetDateTimeCodec implements Codec<OffsetDateTime> {
|
|
@Override
|
public void encode(final BsonWriter writer, final OffsetDateTime value, final EncoderContext encoderContext) {
|
writer.writeString(value.toString());
|
}
|
|
@Override
|
public OffsetDateTime decode(final BsonReader reader, final DecoderContext decoderContext) {
|
return OffsetDateTime.parse(reader.readString());
|
}
|
|
@Override
|
public Class<OffsetDateTime> getEncoderClass() {
|
return OffsetDateTime.class;
|
}
|
}
|
|
DocRepository.java
|
public interface DocRepository extends MongoRepository<DocEntity, String> {
|
public List<DocEntity> findAll();
|
public SchemaDocumentEntity insert(DocEntity formSchemaDocumentEntity);
|
}
|
|
DocEntity.java
|
@Document
|
public class DocEntity {
|
|
@Id
|
private ObjectId documentId;
|
private OffsetDateTime updatedOn;
|
}
|
|