I was trying to modify how ObjectId is serialized by the Jackson Avro 
library. Default serializer creates an AVRO having following structure :

{
    "name" : "id",
    "type" : [ "null", {
      "type" : "record",
      "name" : "ObjectId",
      "namespace" : "org.bson.types",
      "fields" : [ {
        "name" : "counter",
        "type" : {
          "type" : "int",
          "java-class" : "java.lang.Integer"
        }
      }, {
        "name" : "date",
        "type" : [ "null", {
          "type" : "long",
          "java-class" : "java.util.Date"
        } ]
      }, {
        "name" : "machineIdentifier",
        "type" : {
          "type" : "int",
          "java-class" : "java.lang.Integer"
        }
      }, {
        "name" : "processIdentifier",
        "type" : {
          "type" : "int",
          "java-class" : "java.lang.Short"
        }
      }, {
        "name" : "time",
        "type" : {
          "type" : "long",
          "java-class" : "java.lang.Long"
        }
      }, {
        "name" : "timeSecond",
        "type" : {
          "type" : "int",
          "java-class" : "java.lang.Integer"
        }
      }, {
        "name" : "timestamp",
        "type" : {
          "type" : "int",
          "java-class" : "java.lang.Integer"
        }
      } ]
    } ]
  }

However, MongoDB has following format for ObjectId as per official source 
<https://github.com/mongodb/specifications/blob/master/source/extended-json.rst#conversion-table>
 :

{"$oid": <ObjectId bytes as 24-character, big-endian 
*hexstring*>}

So ideally, the AVRO, that I want to generate for this, should have the 
following structure :

{
    "name" : "id",
    "type" : [ "null", {
      "type" : "record",
      "name" : "ObjectId",
      "namespace" : "org.bson.types",
      "fields" : [{
        "name" : "oid",
        "type" : {
          "type" : "string"
        }
      }]
}

What I have been able to do so far is to extend the SerializerModifier and 
use changeProperties to remove all the fields generated by the ObjectId by 
first comparing the class. However, using this approach, I am not able to 
create my own property to add to the List<BeanPropertyWriter> which later 
gets serialized.

public class ObjectIdSerializerModifier extends BeanSerializerModifier {

    @Override
    public List<BeanPropertyWriter> changeProperties(SerializationConfig 
config, BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) {
        if ( beanDesc.getBeanClass().equals(ObjectId.class) ) {
            beanProperties.clear(); // I need to add the 'oid' string element 
here.
        }
        return beanProperties;
    }
}


The above code piece fails with the following error :

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: "Any" type 
(usually for `java.lang.Object`) not supported: `expectAnyFormat` called 
with type [simple type, class org.bson.types.ObjectId]
    at 
com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77)
    at 
com.fasterxml.jackson.dataformat.avro.schema.VisitorFormatWrapperImpl.expectAnyFormat(VisitorFormatWrapperImpl.java:174)
    at 
com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.acceptJsonFormatVisitor(UnknownSerializer.java:66)
    at 
com.fasterxml.jackson.dataformat.avro.schema.RecordVisitor.schemaFieldForWriter(RecordVisitor.java:178)
    at 
com.fasterxml.jackson.dataformat.avro.schema.RecordVisitor.optionalProperty(RecordVisitor.java:121)
    at 
com.fasterxml.jackson.databind.ser.BeanPropertyWriter.depositSchemaProperty(BeanPropertyWriter.java:839)
    at 
com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.acceptJsonFormatVisitor(BeanSerializerBase.java:863)
    at 
com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.acceptJsonFormatVisitor(DefaultSerializerProvider.java:566)
    at 
com.fasterxml.jackson.databind.ObjectMapper.acceptJsonFormatVisitor(ObjectMapper.java:4046)
    at 
com.fasterxml.jackson.databind.ObjectMapper.acceptJsonFormatVisitor(ObjectMapper.java:4025)
    at com.amitds1997.avroserializer.Main.main(Main.java:55)

This is probably because I have emptied the List and it no longer contains 
any elements. So how can I do this? Also, is this the right approach to 
take or should I modify some other parameters and functions?

-- 
You received this message because you are subscribed to the Google Groups 
"jackson-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jackson-user/d973db78-ab42-47b1-b157-2bef7adce0c4%40googlegroups.com.

Reply via email to