2017-08-16 98 views

回答

1

目前(1.8.2的Avro),这是不可能的。生成乔达日期/时间类是硬编码的。

当前master分支已经切换到Java 8并且有一个open issue(与Pull Request)添加与java.time.*类型来生成类的能力。

不幸的是,我不知道任何目前在master中的任何发布计划。如果您觉得冒险,您可以将修补程序应用于1.8.2,因为理论上它应该都是兼容的。序列化/反序列化时的底层基类型仍然是整数和长整数。

0

您需要创建自己的Conversion s到支持java-8日期时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,您可以使用全局GenericData代替,例如:

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

这里是我写在[github]上的测试(https://github.com/holi-java/api-tests/blob/6d09966f007bd6ea6089a5f638275ae0ff5b2a67/avro/src/test/java/test/avro/AvroTypesTest.java# L51_L55)。 –

+1

它不能解决问题:avro编译器仍然为这种逻辑类型生成joda的日期字段。 – injecto