[ 
https://issues.apache.org/jira/browse/AVRO-1490?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13955522#comment-13955522
 ] 

Sean Busbey commented on AVRO-1490:
-----------------------------------

Hi Johan!

Your example schema doesn't set a default value for the nullable fields, so not 
specifying a value does not imply that it ought to be null. If you want this to 
be the case, you should follow the best practice from the spec for nullable 
fields, which would look like

{code}
{"namespace": "AvroSample",
 "type": "record",
 "name": "User",
 "fields": [
     {"name": "name", "type": "string"},
     {"name": "favorite_number",  "type": ["null", "int"], "default": null},
     {"name": "favorite_color", "type": ["null", "string"], "default": null}
 ]
}
{code}

Even with that in place, in the Java API you'd have to use a 
[GenericRecordBuilder|http://avro.apache.org/docs/current/api/java/org/apache/avro/generic/GenericRecordBuilder.html]
 to have defaults filled in for you when writing.

It doesn't look like the C# library includes equivalent functionality yet. Care 
to [make an attempt at adding 
it|https://cwiki.apache.org/confluence/display/AVRO/How+To+Contribute]?

> GenericDatumWriter throws exception for nullable schema fields
> --------------------------------------------------------------
>
>                 Key: AVRO-1490
>                 URL: https://issues.apache.org/jira/browse/AVRO-1490
>             Project: Avro
>          Issue Type: Bug
>          Components: csharp
>    Affects Versions: 1.7.6
>         Environment: Windows, C#, .Net 4.5
>            Reporter: Johan Sundstrom
>
> providing sample code and fix
> Sample Schema:
> {code}
> {"namespace": "AvroSample",
>  "type": "record",
>  "name": "User",
>  "fields": [
>      {"name": "name", "type": "string"},
>      {"name": "favorite_number",  "type": ["int", "null"]},
>      {"name": "favorite_color", "type": ["string", "null"]}
>  ]
> }
> {code}
> Sample code to recreate
> {code}
> namespace AvroSample
> {
>     class Program
>     {
>         static void Main(string[] args)
>         {
>             Schema schema = LoadSchemaFromFile(@"user.avpr");
>             GenericRecord user1 = new GenericRecord((RecordSchema)schema);
>             user1.Add("name", "Alyssa");
>             user1.Add("favorite_number", 256);
>             // Leave favorite color null
>             GenericRecord user2 = new GenericRecord((RecordSchema)schema);
>             user2.Add("name", "Ben");
>             user2.Add("favorite_number", 7);
>             user2.Add("favorite_color", "red");
>             // Serialize user1 and user2 to disk
>             String outPath = @"C:\\users.avro";
>             GenericDatumWriter<GenericRecord> datumWriter = new 
> GenericDatumWriter<GenericRecord>(schema);
>             IFileWriter<GenericRecord> dataFileWriter = 
> DataFileWriter<GenericRecord>.OpenWriter(datumWriter, outPath);
>             dataFileWriter.Append(user1);
>             dataFileWriter.Append(user2);
>             dataFileWriter.Dispose();
>             // Deserialize users from disk
>             
>             IFileReader<User> dataFileReader = 
> DataFileReader<User>.OpenReader(outPath);//, schema);
>             User user = null;
>             while (dataFileReader.HasNext())
>             {
>                 // Reuse user object by passing it to next(). This saves us 
> from
>                 // allocating and garbage collecting many objects for files 
> with
>                 // many items.
>                 user = dataFileReader.Next();
>                 Console.WriteLine("Name={0}", user.name);  
>                 Console.WriteLine(user.ToString());
>             }
>             Console.WriteLine("Press any key to continue...");
>             Console.ReadKey();
>         }
>         static Schema LoadSchema(string json)
>         {
>             Schema schema = Schema.Parse(json);
>             return schema;
>         }
>         static Schema LoadSchemaFromFile(string filePath)
>         {
>             String json = File.ReadAllText(filePath, Encoding.UTF8);
>             return LoadSchema(json);
>         }
>     }
> }
> {code}
> Code that fixes issue:
> {code}
> protected override void WriteRecordFields(object recordObj, 
> RecordFieldWriter[] writers, Encoder encoder)
>         {
>             var record = (GenericRecord) recordObj;
>             foreach (var writer in writers)
>             {
>                   // Change from 
>                   // writer.WriteField(record[writer.Field.Name], encoder);
>                   // to
>                 object result = null;
>                 record.TryGetValue(writer.Field.Name, out result);
>                 writer.WriteField(result, encoder);
>             }
>         }
> }
> {code}



--
This message was sent by Atlassian JIRA
(v6.2#6252)

Reply via email to