[
https://issues.apache.org/jira/browse/AVRO-3103?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17317948#comment-17317948
]
Ryan Skraba commented on AVRO-3103:
-----------------------------------
I haven't tried reproducing but I suspect this is a common mistaken assumption!
{quote}The JSON encoding of an AVRO record should be the same when the schema
AllowNull or not"
{quote}
This is untrue, and causes a bit of confusion... Adding the AllowNull changes
the schema (of course) and the JSON representation is changed as a consequence
{{{"name":{"string":"bob"}}}} is the expected JSON representation if name is
nullable.
{{
{"name":"bob"}
}}is the expected JSON representation if name can only be a string.
and ... {{record.toString()}} is human-readable nonsense that happens to look
like JSON but should never be parsed...
In my experience, the JsonEncoder/Decoders communicate well together, and
across languages where possible, but developers are typically unhappy using
them with a JSON schemas that they've designed themselves.
We've run into this problem with GenericRecords and our workaround was to
transform our records into the JSON expected by our front end manually.
> Wrong JSON encoding with Schema AllowNull
> -----------------------------------------
>
> Key: AVRO-3103
> URL: https://issues.apache.org/jira/browse/AVRO-3103
> Project: Apache Avro
> Issue Type: Bug
> Components: java
> Affects Versions: 1.10.2
> Environment: Java unit test
> Reporter: vincent royer
> Priority: Major
>
> The JSON encoding of an AVRO record should be the same when the schema
> AllowNull or not. In following unit test, the JSON encoded record is
> incorrect when the schema Allow null:
> AvroJsonAllowNullTests.testAvroToJson:82 expected [
> {"name":"bob"}
> ] but found
> [{"name":\{"string":"bob"}}|file://%7B%22name%22:%7B%22string%22:%22bob%22%7D%7D/]
>
> {code:java}
> import org.apache.avro.generic.GenericDatumWriter;
> import org.apache.avro.generic.GenericRecord;
> import org.apache.avro.generic.GenericRecordBuilder;
> import org.apache.avro.io.DatumWriter;
> import org.apache.avro.io.EncoderFactory;
> import org.apache.avro.io.JsonEncoder;
> import org.apache.avro.reflect.ReflectData;
> import org.testng.annotations.Test;
> import java.io.ByteArrayOutputStream;
> import java.io.OutputStream;
> import static org.testng.Assert.assertEquals;
> class AvroJsonAllowNullTests {
> public static class User {
> String name;
> public User(String name) {
> this.name = name;
> }
> public String getName() {
> return name;
> }
> public void setName(String name) {
> this.name = name;
> }
> }
> /**
> * Writes provided {@link org.apache.avro.generic.GenericRecord} into the
> provided
> * {@link OutputStream} as JSON.
> */
> public static void writeAsJson(org.apache.avro.generic.GenericRecord
> record, OutputStream out) throws Exception {
> DatumWriter<GenericRecord> writer =
> new GenericDatumWriter<GenericRecord>(record.getSchema());
> JsonEncoder encoder =
> EncoderFactory.get().jsonEncoder(record.getSchema(), out);
> writer.write(record, encoder);
> encoder.flush();
> }
> @Test
> public final void testAvroToJson() throws Exception {
> org.apache.avro.Schema schema =
> ReflectData.get().getSchema(User.class);
> org.apache.avro.Schema schemaAllowNull =
> ReflectData.AllowNull.get().getSchema(User.class);
> System.out.println("schema=" + schema);
> System.out.println("schemaAllowNull=" + schemaAllowNull);
> GenericRecord record = new GenericRecordBuilder(schema)
> .set("name","bob")
> .build();
> GenericRecord recordAllowNull = new
> GenericRecordBuilder(schemaAllowNull)
> .set("name","bob")
> .build();
> ByteArrayOutputStream baos = new ByteArrayOutputStream();
> ByteArrayOutputStream baosAllowNull = new ByteArrayOutputStream();
> writeAsJson(record, baos);
> writeAsJson(recordAllowNull, baosAllowNull);
> System.out.println("record="+baos.toString());
> System.out.println("recordAllowNull="+baosAllowNull.toString());
> assertEquals(baosAllowNull.toString(), baos.toString());
> }
> }
> {code}
>
--
This message was sent by Atlassian Jira
(v8.3.4#803005)