[ 
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)

Reply via email to