It seems to me that you defined "fields" as an Array (an IndexedRecord) but
you provided input as a single Record. It might help if you change your
JSON document so that "fields" is an array with one element in it (notice
the additional square bracktes [ ] for array notation):

"fields" : [  { "foo": "bar", "spam": "eggs",
                  "answer": 42,
                  "x": {"a": 1}
                 }
              ]

Have you tried this input and does it work if you did?

Pankaj



On Wed, May 8, 2013 at 2:49 PM, David Arthur <mum...@gmail.com> wrote:

> I'm attempting to use Jackson and Avro together to map JSON documents to a
> generated Avro class. I have looked at the Json schema included with Avro,
> but this requires a top-level "value" element which I don't want.
> Essentially, I have JSON documents that have a few typed top level fields,
> and one field called "fields" which is more or less arbitrary JSON.
>
> I've reduced this down to strings and ints for simplicity
>
> My first attempt was:
>
>  {
>     "type": "record",
>     "name": "Json",
>     "fields": [
>       {
>         "name": "value",
>         "type": [ "string", "int", {"type": "map", "values": "Json"} ]
>       }
>     ]
>   },
>
>   {
>     "name": "Document",
>     "type": "record",
>     "fields": [
>       {
>         "name": "id",
>         "type": "string"
>       },
>       {
>         "name": "fields",
>         "type": {"type": "map", "values": ["string", "int", {"type":
> "map", "values": "Json"}]}
>       }
>     ]
>   }
>
> Given a JSON document like:
>
> {
>   "id": "doc1",
>   "fields": {
>     "foo": "bar",
>     "spam": "eggs",
>     "answer": 42,
>     "x": {"a": 1}
>   }
> }
>
> this seems to work, but it doesn't. When I turn around and try to
> serialize this object with Avro, I get the following exception:
>
> java.lang.ClassCastException: java.lang.Integer cannot be cast to
> org.apache.avro.generic.**IndexedRecord
>     at org.apache.avro.generic.**GenericData.getField(**
> GenericData.java:526)
>     at org.apache.avro.generic.**GenericData.getField(**
> GenericData.java:541)
>     at org.apache.avro.generic.**GenericDatumWriter.**writeRecord(**
> GenericDatumWriter.java:104)
>     at org.apache.avro.generic.**GenericDatumWriter.write(**
> GenericDatumWriter.java:66)
>     at org.apache.avro.generic.**GenericDatumWriter.writeMap(**
> GenericDatumWriter.java:173)
>     at org.apache.avro.generic.**GenericDatumWriter.write(**
> GenericDatumWriter.java:69)
>     at org.apache.avro.generic.**GenericDatumWriter.write(**
> GenericDatumWriter.java:73)
>     at org.apache.avro.generic.**GenericDatumWriter.writeMap(**
> GenericDatumWriter.java:173)
>     at org.apache.avro.generic.**GenericDatumWriter.write(**
> GenericDatumWriter.java:69)
>     at org.apache.avro.generic.**GenericDatumWriter.**writeRecord(**
> GenericDatumWriter.java:106)
>     at org.apache.avro.generic.**GenericDatumWriter.write(**
> GenericDatumWriter.java:66)
>     at org.apache.avro.generic.**GenericDatumWriter.write(**
> GenericDatumWriter.java:58)
>
> My best guess is that since the "fields" field is a union, the
> representation of it in the generate class is an Object which Jackson
> happily throws whatever into.
>
> If I change my schema to explicitly use "int" instead of the "Json" type,
> it works fine for my test document
>
>         "type": {"type": "map", "values": ["string", "int", {"type":
> "map", "values": "int"}]}
>
> However now I need to enumerate the types for each level of nesting I
> want. This is not ideal, and limits me to a fixed level of nesting
>
> To be clear, my issue is not modelling my schema in Avro, but rather
> getting Jackson to map JSON onto the generated classes without too much
> pain. I have also tried https://github.com/FasterXML/**
> jackson-dataformat-avro<https://github.com/FasterXML/jackson-dataformat-avro>without
>  much luck.
>
> Any help is appreciated
>
> -David
>
>
>
>
>
>


-- 
Pankaj Shroff
shro...@gmail.com

Reply via email to