1

Is it possible to make an avro schema which is recursive, like

Schema schema = SchemaBuilder
    .record("RecursiveItem")
    .namespace("com.example")
    .fields()
    .name("subItem")
    .type("RecursiveItem")
    .withDefault(null) // not sure about that too...
    .endRecord();

I get a StackOverflowError when using it like that:

static class RecursiveItem {
  RecursiveItem subItem;
}

RecursiveItem item1 = new RecursiveItem();
RecursiveItem item2 = new RecursiveItem();
item1.subItem = item2;

final DatumWriter<RecursiveItem> writer = new SpecificDatumWriter<>(schema);

// note: I actually want a binary output, but I started with some json code I found
ByteArrayOutputStream stream = new ByteArrayOutputStream();
final JsonEncoder encoder = EncoderFactory.get().jsonEncoder(schema, stream);
writer.write(rec1, encoder);
String json = stream.toString();

Note: I also get StackOverflowError if I make the schema using:

Schema schema = ReflectData.get().getSchema(RecursiveItem.class);
Juh_
  • 14,628
  • 8
  • 59
  • 92

1 Answers1

0

Warning: I found a solution to write, but cannot read it bask :-\

I am not sure to really understand, but I manage to make it works with:

  1. ReflectDatumWriter should be used instead of SpecificDatumWriter

  2. I still had issue with schema not found due to automated lookup of schema upon encoding. It looks for a schema with a namespace+name derived automatically. And in my case where the class is a static subclass, the following should be used:

    String cls = RecursiveItem.class.getSimpleName();
    String pck = RecursiveItem.class.getPackage().getName();
    if (RecursiveItem.class.getEnclosingClass() != null) // nested class
      pck = RecursiveItem.class.getEnclosingClass().getName() + "$";
    
  3. To manage the null, the following schema should be used

    Schema schema0 = SchemaBuilder
      .record(cls)
      .namespace(pck)
      .fields()
      .name("subItem")
      .type().unionOf().nullType().and().type("RecursiveItem").endUnion()
      .nullDefault()
      .endRecord();
    
Juh_
  • 14,628
  • 8
  • 59
  • 92