Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add AvroGenerator.Feature.ADD_NULL_AS_DEFAULT_VALUE_IN_SCHEMA for adding default null in generated schema #145

Closed
kucera-jan-cz opened this issue Aug 10, 2018 · 7 comments
Milestone

Comments

@kucera-jan-cz
Copy link

Hello,
currently we are using for generation schema from POJO ReflectData.AllowNull.get() however we would like to switch to jackson-dataformats-binary. The only issue with the switch is absence of "default" value in schema (which we currently have in our schema registry and would break our compatibility). Is it possible to set this behavior through AvroFactory or AvroSchemaGenerator?

For clarification here is example from jackson-dataformats-binary:
{"type":"record","name":"PersonV1","namespace":"dummy","fields":[{"name":"age","type":["null","string"]}]}
And here example from ReflectData.AllowNull.get():
{"type":"record","name":"PersonV1","namespace":"dummy","fields":[{"name":"age","type":["null","string"],"default":null}]}

Thanks in advance for your answer

@kucera-jan-cz kucera-jan-cz changed the title Writing "default" into schema Writing "default" into AVRO schema Aug 10, 2018
@cowtowncoder
Copy link
Member

@kucera-jan-cz Could you include bit more information on code you are using: I assume you have a simple POJO definition (class PersonV1), and then create AvroSchema from it. But how are you serializing it to get output?

@kucera-jan-cz
Copy link
Author

@cowtowncoder Hello and thanks for your reply.
Yes, I am having simple POJO and serializing it with our own serializer with following code:

           int registeredSchemaId = this.schemaRegistry.register(subject, schema);

            ByteArrayOutputStream out = new ByteArrayOutputStream();
            out.write(0);
            out.write(ByteBuffer.allocate(4).putInt(registeredSchemaId).array());

            DatumWriter<Object> dw = new ReflectDatumWriter<>(schema);
            Encoder encoder = ENCODER_FACTORY.directBinaryEncoder(out, null);
            dw.write(value, encoder);
            encoder.flush();
            return out.toByteArray();

@baharclerode
Copy link
Contributor

baharclerode commented Aug 16, 2018

Have you tried using @AvroDefault("null") or @JsonProperty(defaultValue = "null") on the age field?

@cowtowncoder
Copy link
Member

@kucera-jan-cz I meant Jackson code used to produce output that is missing "default" entry. I am not sure I fully understand exact steps of desired Jackson dataformat solution.

@baharclerode
Copy link
Contributor

Oh, I see what you're asking. Currently, Jackson will generate unions for optional fields:

package dummy;

public class PersonV1 {

    public PersonV1(String age) {
        this.age = age;
    }

    private String age;

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
}

Plus

AvroMapper mapper = new AvroMapper();
System.out.println(mapper.schemaFor(mapper.constructType(PersonV1.class)).getSchema()

gives

{
  "type" : "record",
  "name" : "PersonV1",
  "namespace" : "dummy",
  "fields" : [ {
    "name" : "age",
    "type" : [ "null", "string" ]
  } ]
}

But it doesn't generate defaults unless explicitly given one with @AvroDefault("null") or @JsonProperty(defaultValue = "null") because while it already allows nulls by default, it doesn't assume null is the default. We could probably make it add a default without much issue.

@kucera-jan-cz
Copy link
Author

Thanks for your response @cowtowncoder and @baharclerode. Yes it's exactly as you mentioned in your last post - the only missing part is to enable adding "default":null in the schema. Since you mention that you can probably make it I have tried to implement in and send you a pull request.

Regards
Jan

@cowtowncoder cowtowncoder changed the title Writing "default" into AVRO schema Add AvroGenerator.Feature.ADD_NULL_AS_DEFAULT_VALUE_IN_SCHEMA for adding default null in generated schema Aug 30, 2019
@cowtowncoder cowtowncoder added this to the 3.0.0 milestone Aug 30, 2019
@cowtowncoder
Copy link
Member

PR merged, so this is now in for 3.0.0 (and if someone has time & itch, possibly backport in 2.x, currently 2.10).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants