Avro无法将BigDecimal序列化为Decimal logicalType

时间:2018-10-26 14:17:57

标签: java avro

我有一个Avro对象列表,我正在尝试将它们序列化为json并将它们写入磁盘。这是我用来编写的代码。

List<AvroThing> avroThings; // this is populated elsewhere
DatumWriter<AvroThing> writer = new SpecificDatumWriter<>(AvroThing.class);
DataFileWriter<AvroThing> dataWriter = new DataFileWriter<>(writer);
dataWriter.create(AvroThing.getClassSchema(), new File("c:/avrothing.json"));
avroThings.forEach(avroThing -> {
        try {
          dataWriter.append(avroThing);
        } catch (IOException ioe) {
          System.out.println("could not append avroThing");
        }
      });
dataWriter.close();

AvroThing中的一个字段是可为空的十进制类型。

{
  "name":"amount",
  "type":[
    "null",    
    {
      "type":"bytes",
      "logicalType":"decimal",
      "precision":20,
      "scale":0
    }
  ]
}

我用BigDecimal非常简单地填充了它。

Double amount = -750.0;
AvroThing avroThing = new Avrothing();
avroThing.setAmount(BigDecimal.valueOf(amount));

但是,当我尝试使用上面的编写代码对其进行序列化时,出现了此异常:

Not in union ["null",{"type":"bytes","logicalType":"decimal","precision":20,"scale":0}]: -750.0
org.apache.avro.UnresolvedUnionException: Not in union ["null",{"type":"bytes","logicalType":"decimal","precision":20,"scale":0}]: -750.0
    at org.apache.avro.generic.GenericData.resolveUnion(GenericData.java:740)
    at org.apache.avro.generic.GenericDatumWriter.resolveUnion(GenericDatumWriter.java:205)
    at org.apache.avro.generic.GenericDatumWriter.writeWithoutConversion(GenericDatumWriter.java:123)
    at org.apache.avro.specific.SpecificDatumWriter.writeField(SpecificDatumWriter.java:87)
    at org.apache.avro.generic.GenericDatumWriter.writeRecord(GenericDatumWriter.java:156)
    at org.apache.avro.generic.GenericDatumWriter.writeWithoutConversion(GenericDatumWriter.java:118)
    at org.apache.avro.generic.GenericDatumWriter.write(GenericDatumWriter.java:75)
    at org.apache.avro.generic.GenericDatumWriter.write(GenericDatumWriter.java:62)

我尝试使用BigDecimal.setScale(0, RoundingMode.UP),但这除了将小数点后的最后几个数字四舍五入外没有任何改变。 Avro Docs说精度是a JSON integer representing the (maximum) precision of decimals stored in this type (required).,并且由于BigDecimal无法独立于小数位数更改精度,因此我认为这不是解决方案。

我认为架构是正确的,但是本质上我们只想允许不超过20位的任何值,而与小数点的位置无关(因此20202039848780.202378249都应接受) 。有什么想法吗?

0 个答案:

没有答案