FasterXML / FasterXML/jackson-dataformats-binary

Missing "null" default values when generating schema

Aberta
#207 10 comentários 1 reação 0 responsáveis Ver no GitHub
avro
Linguagem predominante
Java
Estrelas
347
Forks
156
Merge médio
3d 3h
PRs com merge (30d)
22

Descrição

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.

Guia de contribuição

Nenhum guia de contribuição indexado para este repositório

Avaliação

Esta issue ainda não foi avaliada.

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.