FasterXML / FasterXML/jackson-dataformats-binary

Missing "null" default values when generating schema

未关闭
#207 10 条评论 1 个 reaction 已指派 0 人 在 GitHub 查看
avro
主要语言
Java
星标
347
派生
156
平均合并
3 天 3 小时
30 天内合并 PR
22

描述

After upgrading from jackson `2.10.3` to `2.11.0` and using avro `1.9.2`, I noticed that the schema generation is broken regarding default "null" values for union types.

Exemple POJO :

```
public class Book {

@JsonProperty(defaultValue = "null")
private String title;

public Book() {
}

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

}
```

Code to generate the JSON schema :

```
AvroMapper mapper = new AvroMapper(new AvroFactory());
com.fasterxml.jackson.dataformat.avro.schema.AvroSchemaGenerator gen = new com.fasterxml.jackson.dataformat.avro.schema.AvroSchemaGenerator();
mapper.acceptJsonFormatVisitor(Book.class, gen);
AvroSchema schemaWrapper = gen.getGeneratedSchema();
org.apache.avro.Schema schema = schemaWrapper.getAvroSchema();
System.out.println(schema.toString(true));
```

With version 2.10.3 we had :

```
{
"type": "record",
"name": "Book",
"namespace": "com.example",
"fields": [
{
"name": "title",
"type": [
"null",
"string"
],
"default": null
}
]
}
```

Now with version 2.11.0 we have :

```
{
"type": "record",
"name": "Book",
"namespace": "com.example",
"fields": [
{
"name": "title",
"type": [
"null",
"string"
]
}
]
}
```

The `default` field in the schema is missing when generating the schema with version `2.11.0`

After short analysis, I have noticed than in the `org.apache.avro` class, the method `hasDefaultValue` always returns `false`, so when generating the json schema output in the `fieldsToJson` method, this code never write the default field :

```
if (f.hasDefaultValue()) {
gen.writeFieldName("default");
gen.writeTree(f.defaultValue());
}
```

The `Field` instance is instanciated by `com.fasterxml.jackson.dataformat.avro.schema.RecordVisitor` and it seems to mess up with the default value :

```

JsonNode defaultValue = AvroSchemaHelper.parseDefaultValue(prop.getMetadata().getDefaultValue());
writerSchema = this.reorderUnionToMatchDefaultType(writerSchema, defaultValue);
Field field = new Field(prop.getName(), writerSchema, prop.getMetadata().getDescription(), AvroSchemaHelper.jsonNodeToObject(defaultValue));
AvroMeta meta = (AvroMeta)prop.getAnnotation(AvroMeta.class);
if (meta != null) {
field.addProp(meta.key(), meta.value());
}
```

When debugging, with this `Book` class :
- `JsonNode defaultValue` contains an instance of `NullNode`
- `AvroSchemaHelper.jsonNodeToObject(defaultValue)` returns null
- in the `Field` constructor there is a weird comparison `defaultValue == NULL_DEFAULT_VALUE` where NULL_DEFAULT_VALUE = new Object()
- it results in the default `NullNode` default value being completely forgotten and replaced by null which results in no default value at all

Did something change to how I should specify a default value on a POJO field ?
I tried with @JsonProperty and @AvroDefault but none work.

贡献指南

这个仓库没有索引到贡献指南

评估

这个 Issue 还没有评估数据。

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。