Avro с датами Java 8 в качестве логического типа

последний компилятор Avro (1.8.2) генерирует источники java для нужные логического типа С Joda Времени реализаций на основе. Как настроить компилятор Avro для создания источников, использующих Java 8 date-time API?

2 ответов


В настоящее время (avro 1.8.2) это невозможно. Он жестко закодирован для создания классов даты/времени Joda.

текущего master филиал перешел на Java 8 и открыть вопросPull-Запрос), чтобы добавить возможность создавать классы с java.time.* типы.

Я понятия не имею о каком-либо графике выпуска для того, что в настоящее время находится в master к сожалению. Если вы чувствуете приключений, вы можете применить патч к 1.8.2, С теоретически все должно быть совместимо. Базовые типы при сериализации / десериализации по-прежнему являются целыми числами и длинными.


вам нужно создать свой собственный преобразованиеs Для поддержки Java-8 date-time api, ниже приведено преобразование для 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);
    }
}

логические типы можно повторно использовать в avro, поэтому вы можете использовать существующий date логический тип, например:

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

для сериализации и десериализации вы должны установить GenericData который найдет ваше собственное преобразование, например:

//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;
}

если вы не хотите настраивать GenericData каждый раз, вы можете использовать global GenericData вместо этого, например:

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