简体   繁体   中英

Recursive schema with avro (SchemaBuilder)

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

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(); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM