Uploaded image for project: 'Java Driver'
  1. Java Driver
  2. JAVA-2829

Handling OffsetTimeStamp

    • Type: Icon: Task Task
    • Resolution: Works as Designed
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: 3.6.3
    • Component/s: Codecs
    • None
    • Environment:
      Spring Boot 2.0.1.RELEASE
    • None
    • None
    • None
    • None
    • None
    • None
    • None

      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;
      }
      

            Assignee:
            Unassigned Unassigned
            Reporter:
            ginsul Gintautas Sulskus
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved:
              None
              None
              None
              None