Avro with Java 8 dates as logical type

徘徊边缘 提交于 2020-01-01 01:55:08

问题


Latest Avro compiler (1.8.2) generates java sources for dates logical types with Joda-Time based implementations. How can I configure Avro compiler to produce sources that used Java 8 date-time API?


回答1:


Currently (avro 1.8.2) this is not possible. It's hardcoded to generate Joda date/time classes.

The current master branch has switched to Java 8 and there is an open issue (with Pull Request) to add the ability to generate classes with java.time.* types.

I have no idea on any kind of release schedule for whatever is currently in master unfortunately. If you feel adventurous you can apply the patch to 1.8.2, since in theory it should all be compatible. The underlying base types when serializing / deserializing are still integers and longs.




回答2:


You need to create your own Conversions to support java-8 date-time api, below is a conversion for java.time.LocalDate:

class Java8LocalDateConversion extends Conversion<LocalDate> {
    @Override
    public Class<LocalDate> getConvertedType() {
        return LocalDate.class;
    }

    @Override
    public String getLogicalTypeName() {
        //      v--- reuse the logical type `date`
        return "date";
    }

    @Override
    // convert LocalDate to Integer
    public Integer toInt(LocalDate value, Schema schema, LogicalType type) {
        return (int) value.toEpochDay();
    }

    @Override
    // parse LocalDate from Integer
    public LocalDate fromInt(Integer value, Schema schema, LogicalType type) {
        return LocalDate.ofEpochDay(value);
    }
}

The logical types can be reused in avro, so you can using the existing date logical type, for example:

Schema schema = LogicalTypes.date().addToSchema(Schema.create(Type.INT));

For the serializing & deserializing you should set the GenericData which will find your own conversion, for example:

//serializing
DatumWriter<T> out = new SpecificDatumWriter<>(schema, data());

// deserializing
DatumReader<T> in = new SpecificDatumReader<>(schema, schema, data());

private SpecificData data() {
    SpecificData it = new SpecificData();
    it.addLogicalTypeConversion(new Java8LocalDateConversion());
    return it;
}

If you don't want to configure the GenericData every time, you can use the global GenericData instead, for example:

//      register the conversion globally ---v
SpecificData.get().addLogicalTypeConversion(new Java8LocalDateConversion());


来源:https://stackoverflow.com/questions/45712231/avro-with-java-8-dates-as-logical-type

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!