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.