2017-08-16 42 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